从php启动php文件作为后台进程而不用exec()

时间:2012-02-24 13:30:08

标签: php background exec

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

我考虑到了这一点:

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

我的虚拟主机只禁用了对exec()的访问权限。

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

有没有人知道任何解决方案?

2 个答案:

答案 0 :(得分:5)

您可以通过使用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 );

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

<强>更新
如本问题所述:sending a non-blocking HTTP POST request 在脚本作业中,您可以发送此标头以在脚本运行时关闭连接:

// 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 );没有创建异步请求。我还没有找到怎么做。

答案 1 :(得分:1)

我没有对此进行过测试,但是如果你能够使用curl,你可以使用ignore_user_abort()创建background.php并使用低超时从主脚本中卷曲它。用户看到的脚本会稍微延迟,因为它必须等待卷曲请求超时,但您的后台应该继续工作。