提问人:adrianTNT 提问时间:1/18/2012 最后编辑:adrianTNT 更新时间:3/8/2013 访问量:17336
在 PHP 中执行 exec() 或 system() 并且不等待输出
Executing an exec() or system() in PHP and do not wait for output
问:
我想从PHP脚本触发eider exec()或system()中的shell命令,但这是一个需要一段时间才能完成的任务,有没有办法触发它并继续运行PHP页面加载而不会延迟?
编辑:我在 CentOS 6、PHP 5.3 上
答:
-1赞
poojitha
1/18/2012
#1
好吧,使用 ajax 请求来激活执行部分......然后继续执行其他任务
评论
0赞
adrianTNT
1/18/2012
它可能会起作用,但应该有一种更简单、更可靠的方法,比如 exec() 或 system() 末尾的参数;
0赞
hummingBird
1/18/2012
我没有得到 -1 级别。盖伊给出了一个简短的回答。也许不喜欢,但仍然是一个公平的。
0赞
user1447420
9/16/2017
在尝试了任何其他解决方案后,终于设法使用您的建议使其工作。谢谢!
0赞
Uku Loskit
1/18/2012
#2
这应该有效:
shell_exec("nohup yourcommand > /dev/null 2> /dev/null &");
编辑:对不起,不知道为什么我排除了&将其放入bg 2> 将 STDOUT 和 STDERR 重定向到 /dev/null。
评论
0赞
adrianTNT
1/18/2012
命令运行但存在延迟,这是完整的命令:shell_exec("ffmpeg -i 'videos/sample.mp4' -qmax 1 -vframes 1 -ss 80 videos/images/1.jpg 2> /dev/null");
0赞
Uku Loskit
1/18/2012
尝试: shell_exec(“nohup ffmpeg -i 'videos/sample.mp4' -qmax 1 -vframes 1 -ss 80 videos/images/1.jpg > /dev/null 2> /dev/null”)
0赞
adrianTNT
1/18/2012
同样的延迟,命令执行得很好。也许 ffmpeg 只是行为不同?
0赞
Uku Loskit
1/18/2012
刚刚用 PHP 和 ffmpeg 测试了一下,现在它可以工作了。
17赞
Eduard Luca
1/18/2012
#3
取决于您使用的操作系统。
对于 linux:
pclose(popen("php somefile.php &","r"));
注意末尾的 amperstand(非常重要)。
对于 Windows:
pclose(popen("start php.exe somefile.php","r"));
在这里,关键字很重要。start
希望这会有所帮助。
评论
1赞
adrianTNT
1/18/2012
我试过了,延迟是一样的,然后如果我设置了一个内部video_processor.php那么我的父脚本也会等待 10 秒。exec("php video_processor.php &");
sleep(10)
0赞
Eduard Luca
1/18/2012
尝试使用 or(我假设您的 PHP 安装在默认位置)pclose(popen("php video_processor.php &","r"));
pclose(popen("/usr/bin/php video_processor.php &","r"));
0赞
adrianTNT
1/18/2012
它适用于这个:所以后来我编辑了我的,它起作用了:谢谢。:p arty: :)pclose(popen("php video_processor.php &","r"));
pclose(popen("ffmpeg -i 'videos/sample.mp4' -qmax 1 -vframes 1 -ss 80 videos/images/1.jpg &","r"));
0赞
Matt Korostoff
4/5/2015
哇,我简直不敢相信这是多么容易和简单!绝妙的解决方案!我之前对此进行了一些详细的研究,并且所有其他解决方案都推荐了用于分叉或线程化 PHP 进程的复杂策略。
1赞
MSC
5/11/2017
Windows 特定注释:我曾经使用过: pclose(popen(“start /B php.exe somefile.php”,“r”));自 Windows 10 创意者更新 (1703) 起 - “start”命令的“/B”后台开关不起作用。很高兴看到它不需要。
3赞
Darren Newton
1/18/2012
#4
这并不能直接回答您的问题,但您应该考虑使用 cron 作业或使用 Beanstalkd 等队列在后台进程中执行视频转换工作。
这样,您就可以在后台堆叠您的 ffmpeg 工作,而不会阻塞您的 Web 服务器。
过去,我在这两种方法(cron / queue)上都取得了很大的成功。
有关后台进程的其他一些帖子:
您可能会发现一些有用的工具:
http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/
Pheanstalk,一个用于 PHP 的 Beanstalkd 库
2赞
Michael J. Calkins
3/8/2013
#5
我做什么:
public function post_create()
{
ob_end_clean();
header("Connection: close");
ignore_user_abort(); // optional
ob_start();
echo "Tell ajax to gtfo!";
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush(); // Strange behaviour, will not work
flush(); // Unless both are called !
// Do processing here
}
评论
0赞
Zombo
7/13/2020
似乎只适合我header('Content-Length:0');flush();
评论