如何在PHP 7之前版本中从另一PHP文件后台执行PHP文件
在PHP 7之前版本实现后台进程执行
看来你在PHP7之前的版本里搞后台进程踩了坑,之前试的exec和curl方案没成功,多半是细节没处理到位。下面给你几个靠谱的解决思路和代码示例,帮你实现调用file_a.php时不用等5秒,直接让file_b.php在后台跑的效果:
一、修复你的exec方案
你之前的exec命令没成功,大概率是没彻底脱离当前进程的上下文,也没处理标准错误输出。给你调整一下:
echo "Start ".time()."<br>"; // 用nohup让进程脱离终端,同时重定向标准输出和错误到/dev/null exec("nohup php -f /Path/to/file/file_b.php > /dev/null 2>&1 &"); echo "End ".time()."<br>";
为啥之前的exec不行?
你之前只重定向了标准输出到/dev/null,但没处理标准错误流(也就是2>&1这部分),而且没加nohup——当当前的PHP进程结束时,系统可能给后台的php进程发终止信号,导致它直接挂掉。加了nohup之后,后台进程会忽略挂起信号,就算父进程退出也能继续运行。
另外还要注意两个点:
- 如果系统里
php命令不在默认PATH里,得用绝对路径,比如/usr/bin/php,避免找不到命令 - 检查权限:运行PHP的服务器用户(比如www-data)得有读取和执行file_b.php的权限
二、用proc_open替代exec(更灵活可控)
proc_open是PHP自带的进程控制函数,在PHP7之前完全支持,能更精细地控制子进程的输入输出,不用担心依赖系统命令的问题:
echo "Start ".time()."<br>"; // 定义子进程的输入输出规则:把标准输出和错误都丢去/dev/null $descriptorspec = array( 0 => array("pipe", "r"), // 标准输入,我们不用写,所以设为管道 1 => array("file", "/dev/null", "w"), // 标准输出重定向 2 => array("file", "/dev/null", "w") // 标准错误重定向 ); // 启动子进程 $process = proc_open("php -f /Path/to/file/file_b.php", $descriptorspec, $pipes); if (is_resource($process)) { // 关闭输入管道,避免进程挂起等待输入 fclose($pipes[0]); // 直接关闭进程句柄,不等待子进程完成 proc_close($process); } echo "End ".time()."<br>";
这个方法不需要依赖nohup,直接通过PHP自身的函数就能让子进程后台跑起来,稳定性更高。
三、给你的curl方案补个bug
你之前的curl设置了CURLOPT_TIMEOUT_MS为1毫秒,这时间太短了,服务器可能还没来得及接收请求就被中断了,所以file_b.php根本没启动。如果想用HTTP触发的方式,可以调整一下参数:
echo "Start ".time()."<br>"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://192.168.1.1:8888/file/file_b.php'); curl_setopt($ch, CURLOPT_FRESH_CONNECT, true); curl_setopt($ch, CURLOPT_TIMEOUT_MS, 100); // 给服务器留100毫秒接收请求的时间 curl_setopt($ch, CURLOPT_NOSIGNAL, true); // 避免系统信号中断进程(PHP7之前某些系统需要) curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_exec($ch); curl_close($ch); echo "End ".time()."<br>";
不过这种方式依赖Web服务器正常运行,而且如果file_b.php执行时间长,可能会占用Web服务器的连接池,所以更推荐用exec或proc_open的方式。
最后提几个注意事项
- 你file_b.php里的
set_time_limit(5)刚好够那4次sleep,但如果后续要加更多操作,得把这个值调大,或者设为0(表示无时间限制) - 邮件发送可能会因为服务器的邮件队列延迟,就算file_b.php后台跑起来了,邮件也可能不会立刻收到,这是正常的
- 如果是Windows服务器,命令得调整,比如用
start /B php.exe -f "C:\Path\to\file_b.php"替代nohup的写法
内容的提问来源于stack exchange,提问作者user31929
相关产品推荐
相关产品推荐

