从php启动php文件作为后台进程,无需执行()


Launch php file from php as background process without exec()

我想使用另一个PHP脚本在后台运行一个PHP剧本。

我想到了这个:

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

我的网络主机只禁用了对exec()的访问。

我唯一能想到的另一种方法是向电子邮件转发器发送一个邮件(),然后通过管道发送到脚本,但这是一个古怪的解决方案,而不是一个解决方案。

有人知道解决方案吗?

您可以通过使用curl并将脚本作为web资源加载以便执行来实现这一点。如果该脚本需要保护不公开,您可以检查请求是否来自同一服务器:

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

请确保使用curl发出异步请求,这样,如果脚本需要大量时间执行,就不会挂起原始用户请求(使用curl_setopt( $handle, CURLOPT_HEADER, false );

因此,计划是从您知道需要执行脚本的页面开始,向脚本发起Http请求(这是使用curl库的一个非常基本的示例):

$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 );

然后在您的脚本中,使用上面的脚本来保护未从当前服务器混合的请求,并完成该工作。

更新
如本问题所述:发送非阻塞HTTPPOST请求在脚本作业中,您可以在脚本运行时发送此标头以关闭连接:

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

更新的II
回顾我自己的回答,我已经检查了curl_setopt( $handle, CURLOPT_HEADER, false );没有创建异步请求。我仍然没有找到如何做到这一点。

我还没有测试过这一点,但如果你能使用curl,你可以用ignore_user_abort()创建background.php,并在较短的超时时间内从主脚本中卷曲它。用户看到的脚本会稍微延迟,因为它必须等待curl请求超时,但后台应该继续工作。