阻止php exec等待

时间:2014-03-07 22:00:22

标签: php ajax asynchronous exec

我已经工作了一段时间尝试获取一些PHP代码以异步方式运行我已经看过各种帖子。

我希望我的脚本运行一些额外的格式,但是快速返回脚本而不是等待exec命令响应这是我的代码到目前为止。

//convert ogg
exec("cd {$targetDir}/ && ffmpeg -i {$tmpname}.wav -c:a libvorbis out.ogg > /dev/null 2>/dev/null &");                              
//convert mp3
exec("cd {$targetDir}/ && ffmpeg -i {$tmpname}.wav out.mp3 > /dev/null 2>/dev/null &");

return ajax response

有人可以告诉我这是否可行并且可以完成

2 个答案:

答案 0 :(得分:1)

问题是在使用&进行后台处理之前,您正在运行几个不同的命令链接在一起。

将整个命令粘贴在()中,然后添加&

exec("(cd {$targetDir}/ && ffmpeg -i {$tmpname}.wav -c:a libvorbis out.ogg > /dev/null 2>/dev/null ) &");                              
exec("(cd {$targetDir}/ && ffmpeg -i {$tmpname}.wav out.mp3 > /dev/null 2>/dev/null ) &");

如果你需要来自exec的返回值,但不想在回复用户之前等待它,你总是可以将exec坚持在一个对象的解构器中...考虑一个糟糕的人工作队列:))

如果您需要对exec结果执行某些操作

,这是一个示例
class Foo(){

    public function __destruct(){
        //These exec's won't be backrounded, but this method is only call after the object is
        //  is being garbage collected, so the user's not waiting on the results
        exec("cd {$targetDir}/ && ffmpeg -i {$tmpname}.wav -c:a libvorbis out.ogg > /dev/null 2>/dev/null ");                   
        exec("cd {$targetDir}/ && ffmpeg -i {$tmpname}.wav out.mp3 > /dev/null 2>/dev/null ");

        //exec's are done, now do anything else you want here...
    }

}

使用这种方法的一个警告是,即使客户端已经移动,进程仍在运行,消耗内存,如果使用php-fpm,它正在执行进程。

执行此操作的“真正”方法(离线处理)是一个基本的作业排队服务器 - 这个主题远远超出了这篇文章的内容

答案 1 :(得分:0)

我会采取不同的方法:

  1. 在作业队列中的数据库中添加作业;
  2. 有一个尚未处理的的cron作业处理作业未处理;该脚本将从数据库加载最旧的未处理和未处理的项目,设置“正在处理”标志并同步运行作业;
  3. 当作业完成时(与同步的脚本相同),将其标记为已处理并向所有者发送邮件。
  4. 您甚至可以让页面检查相同的数据库以获取用户的状态;在队列中,以最简单的形式处理和完成。