我想使用另一个PHP脚本在后台运行PHP脚本。
我考虑到了这一点:
exec('/usr/bin/php background.php &');
我的虚拟主机只禁用了对exec()的访问权限。
我能想到的唯一另一种方法是将邮件()发送到通过管道传输到脚本的电子邮件转发器,但这是一个古怪的解决方法,而不是解决方案。
有没有人知道任何解决方案?
答案 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并使用低超时从主脚本中卷曲它。用户看到的脚本会稍微延迟,因为它必须等待卷曲请求超时,但您的后台应该继续工作。