2014-03-31 37 views
0

我试图找到一种方法,我可以回显exec调用的输出,然后在进程运行时将其刷新到屏幕。我写了一个简单的PHP脚本,它接受文件上传,然后使用FFMPEG转换文件,如果它不是适当的文件类型。我在Windows机器上做这个。目前我的命令看起来像这样:PHP执行 - 在进程中逐行回显输出

$cmd = "ffmpeg.exe -i ..\..\uploads\\".$filename." ..\..\uploads\\".$filename.".m4v 2>&1"; 
exec($cmd, $output); 

我需要的是这样的:

while($output) { 
    print_r($output); 
    ob_flush(); flush(); 
} 

我读过有关使用ob_flush()flush()清除输出缓冲区,但我只得到一次过程输出已完成。该命令完美工作,它只是在转换时不更新页面。我想有一些输出,所以这个人知道发生了什么。

我已经设置了超时

set_time_limit(10 * 60); //5 minute time out 

,他很感激,如果有人可以把我在正确的方向。我查看了一些接近一个Stackoverflow的解决方案,但没有一个似乎奏效。

回答

0

exec()阻止调用,并且不会将控制权返回给PHP,直到外部程序终止。这意味着你不能做任何事情来逐行转储输出,因为PHP在外部应用程序运行时暂停。

对于你想要的,你需要使用proc_open,它返回一个你可以在循环中读取的文件句柄。例如

$fh = proc_open('.....'); 
while($line = fgets($fh)) { 
    print($line); 
    flush(); 
} 
0

有两个问题的方法:

首先是,作为@Marc b注意,事实上,exec将阻塞,直到它完成。你必须设计一些测量进度的方法。

第二个是,以这种方式使用ob_flush()等于保持服务器的客户端打开和一次一点点运送数据之间的连接。这不是HTTP协议的设计目的,虽然它有时可能有效,但它不会一致地工作 - 不同的浏览器和不同的服务器会超时。更好的方法是通过AJAX调用:使用Javascript的setTimeout()函数(或setInterval()),定期调用服务器并让服务器发回进度报告。

1

由于exec调用是阻塞调用,因此您无法使用缓冲区获取状态。

相反,您可以将系统调用中的输出重定向到日志文件。让客户端向服务器查询进度更新,在这种情况下,服务器可以解析日志文件的最后几行以获取有关当前进度的信息并将其发送回客户端。