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

ONO*_*NOZ 1 php background exec

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

我考虑到了这一点:

exec('/usr/bin/php background.php &');
Run Code Online (Sandbox Code Playgroud)

我的webhost只禁用了对exec()的访问权限.

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

有谁知道任何解决方案?

Raú*_*ràs 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();
}
Run Code Online (Sandbox Code Playgroud)

确保使用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 );
Run Code Online (Sandbox Code Playgroud)

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

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

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

更新了II
查看我自己的答案,我已经检查过curl_setopt( $handle, CURLOPT_HEADER, false );它不会创建异步请求.我还没有找到怎么做.

  • 啊,明白了!`curl_setopt($ handle,CURLOPT_TIMEOUT,1);`它确实会产生竞争条件; 如果连接时间超过1秒,则无法正常工作.也.它让用户等待一秒钟,但我想我只需要接受它. (2认同)
  • 如果作业仍在工作,您将需要开发一种阻止第二个访问者运行后台请求的方法. (2认同)