Launch php file from php as background process wit

2019-07-25 17:38发布

I want to run a PHP script in the background using another PHP script.

I had this in mind:

exec('/usr/bin/php background.php &');

My webhost has only disabled access to exec().

The only other way I can think of is sending a mail() to an email forwarder which is piped to a script, but that's rather a wacky workaround than a solution.

Does anyone know any solution?

2条回答
2楼-- · 2019-07-25 17:55

You could achieve that by using curl and loading the script as a web resource so it can be executed. If that script needs to be protected from public, you can check if the request came from the same server:

if( $_SERVER['SERVER_NAME'] != 'localhost' 
        || $_SERVER['REMOTE_ADDR'] != '127.0.0.1'
        || stripos( $_SERVER['HTTP_USER_AGENT'], 'wget' )===false
        )
{
    // Access Denied!!
    die();
}

Be sure to make an asynchronous request with curl, so if the script takes a lot of time to execute, doesn't hang the original user request (use curl_setopt( $handle, CURLOPT_HEADER, false );

So the plan is from the page where you know you need to execute the script, launch an Http request to the script (this is a very basic example of using curl library):

$handle = curl_init();
curl_setopt( $handle, CURLOPT_URL, 'http://localhost/your_script.php');
curl_setopt( $handle, CURLOPT_HEADER, false );
curl_exec( $handle );
curl_close( $handle );

Then in your script, use the above script to protect requests not comming from current server, and do the job.

Updated
As stated in this question: sending a non-blocking HTTP POST request In your script job you could send this header to close the connection as script is running:

// Send the response to the client
header('Connection: Close');
// Do the background job: just don't output anything!

Updated II
Reviewing my own answer, I've checked that curl_setopt( $handle, CURLOPT_HEADER, false ); does not create an asynchronous request. I still have not found how to do it.

查看更多
疯言疯语
3楼-- · 2019-07-25 18:15

I haven't tested this, but if you are able to use curl, you could possibly create background.php with ignore_user_abort() and curl it from your main script with a low timeout. The script the user sees will be delayed slightly because it has to wait for the curl request to timeout, but your background should continue working.

查看更多
登录 后发表回答