在等待PHP执行时,我可以将哪些内容发送回浏览器?

所以….我有一个涉及很多后端执行的PHP页面,即'exec'调用在主机服务器上运行shell命令。

这可能需要几分钟时间,具体取决于所涉及的电话。 (如果你看下面的话,通过exec调用的每个recursion都会挂载一个LUN,每次执行的时候有时候会多达100个。)我很好奇我能做些什么来将内容发送回浏览器(并阻止它从超时)。

<!DOCTYPE html> <html> <head> <title>sfvmtk</title> </head> <body> <?php // TEMPORARY VARIABLES FOR TESTING $hba = 'vmhba38'; $svip = '10.10.20.100'; $targets = array ( 0 => array ( 'iqn' => 'iqn.2010-01.com.sf:t5np.esxtest.41', 'account' => 'esx', 'isecret' => 'isecret00000', 'tsecret' => 'tsecret00000' ), 1 => array ( 'iqn' => 'iqn.2010-01.com.sf:t5np.esxtest2.42', 'account' => 'esx2', 'isecret' => 'isecret00001', 'tsecret' => 'tsecret00001' ) ); $hostname = $_REQUEST['hostname']; $username = $_REQUEST['username']; $password = $_REQUEST['password']; foreach ($targets as $ctarget) { exec('esxcli -s '.$hostname.' -u '.$username.' -p '.$password.' iscsi adapter discovery statictarget add -A '.$hba.' -a '.$svip.' -n '.$ctarget['iqn'], $out); exec('esxcli -s '.$hostname.' -u '.$username.' -p '.$password.' iscsi adapter target portal auth chap set -A '.$hba.' -a '.$svip.' -N '.$ctarget['account'].' -d uni -l required -n '.$ctarget['iqn'].' -S '.$ctarget['isecret'], $out); exec('esxcli -s '.$hostname.' -u '.$username.' -p '.$password.' iscsi adapter target portal auth chap set -A '.$hba.' -a '.$svip.' -N '.$ctarget['account'].' -d mutual -l required -n '.$ctarget['iqn'].' -S '.$ctarget['tsecret'], $out); } exec('vicfg-rescan --server '.$hostname.' --username '.$username.' --password '.$password.' '.$hba, $out); ?> </body> </html> 

使用jQuery和Ajax来处理DIV中的上述任务。 对于超时,你需要调整php.ini的networking服务器(或修改Apache的.htaccess中)。 当脚本本身忙于工作时,脚本本身没有真正的方法来报告。

您可以尝试在每个循环中放入一个echoprintf ,我经常尝试这个技巧很多次,输出不会caching,直到脚本结束。 这需要反复试验。 如果你有很多logging,这个技巧是否可以工作,我会在每个循环中做这个:

 echo "."; if( $i++%100 == 0 ) echo "\n"; 

这样,点遍历整个页面,直到100列/循环/logging然后开始一个新的行。

你是否考虑过像Gearman这样的任务的一个抽象层? 您可以轮询后端,并在执行时保持响应的前端或将用户locking到页面。

对于通过HTTP调用的任何长时间运行的进程,解决scheme通常是asynchronous处理 (即从Web服务器分离进程组)。

你可以在一个特别优化的Web服务器上处理很长时间的请求,但只有当所有介入HTP的设备准备好使用(使用SSL都可以)的时候。 但是在这个configuration中不可能显示处理的范围OTOH对由单独进程生成的日志文件进行轮询可以通过简短的自动刷新HTTP请求来完成。

你需要使用proc_open http://www.php.net/manual/en/function.proc-open.php,proc_get_status http://php.net/manual/en/function.proc-get-status.php ,stream_set_blocking http://php.net/manual/en/function.stream-set-blocking.php以及睡眠http://php.net/manual/en/function.sleep.php和呼应和冲洗应该工作好&#x3002;

这可以防止PHP从父apache处理程序中超时和死亡,所以你需要刷新PHP缓冲区到Apache,但这并不意味着数据将被发送到客户端,因为有兑现,压缩等等,所以在这种情况下,您需要使用http / xml请求(ajax)来检查另一个进程,并且可以使用DB,文件系统,caching或会话来处理这些信息。 更进一步,您需要妥善保护它,您将运行不同帐户的stream程和网站,所以没有人可以从您的网站运行命令。