如何同时(同步)运行 2 个 PHP 脚本来监控 popen 命令?
我有一个脚本启动这样的命令:
7za a -t7z -mx9 backup.7z "H:\Informatique\*"
我想在使用 jQuery 和 PHP 的页面上显示压缩的进度。
运行此命令的 php 脚本如下所示:
if( ($fp = popen("7za a -t7z ".$GLOBALS["backup_compression"]." \"".$backuplocation.$backupname."\" \"".$pathtobackup."\"", "r")) ) {
while( !feof($fp) ){
$fread = fread($fp, 256);
$line_array = preg_split('/\n/',$fread);
$num_lines = count($line_array);
$_SESSION['job'][$jobid]['currentfile'] = $_SESSION['job'][$jobid]['currentfile']+$num_lines;
$num_lines = 0;
flush();
}
pclose($fp);
}
jQuery 调用 7za 脚本,然后 jquery每 1000 毫秒调用一次侦听器 ( listener.php )。listener.php 页面包含以下代码:
session_start();
$jobid = $_GET['jobid'];
if(!isset($_SESSION['job'][$jobid])) { $arr = array("error"=>"Job not found"); echo json_encode($arr); exit(); };
$arr = array(
"curfile" => $_SESSION['job'][$jobid]['currentfile'],
"totalfiles" => $_SESSION['job'][$jobid]['totalfiles'],
);
echo json_encode($arr);
$jobid = null;
$arr = null;
exit();
在 jquery 调用完成后(使用侦听器并且我们从服务器得到响应),我们会以正常的方式显示信息,例如:$("currentfile").text(data['curfile']);
问题是监听器处于无限循环中等待第一个脚本完成......这不是监听器的工作......它在一切结束时监听......当你倾听时,它是为了知道什么正在发生。:P
你知道发生了什么,我该如何解决这个问题?或者也许你可以帮助我解决这个问题的新方法?
与往常一样,欢迎提出任何建议。谢谢你。
编辑
jQuery脚本:
function backup_launch(jobid) {
x('jobid: '+jobid+' on state '+state);
x('Listener launched');
listen(jobid);
timeout = setTimeout("listen('"+jobid+"')", 500);
$.ajax({
url:'backup.manager.php?json&jobid='+jobid+'&state='+state,
dataType:'json',
success:function(data)
{
state = 3;
}
});
}
function listen(jobid) {
$.ajax({
url:'backup.listener.php?json&jobid='+jobid,
dataType:'json',
success:function(data)
{
var curfile = data['curfile'];
var totalfiles = data['totalfiles'];
var p = curfile * 100 / totalfiles;
x('File '+curfile+' out of '+totalfiles+' progress%: '+p);
timeout = setTimeout("listen('"+jobid+"')", 500);
}
});
}
编辑 2 我找到了 Gearman (http://gearman.org/),但我根本不知道如何实现它,它需要是可移植的/独立的......我会尝试对此进行调查。
编辑 3
backup.manager.php页面的完整代码。该脚本正在发送响应,但在后台执行该工作。
在返回任何结果之前,listen.php 页面仍在等待命令完成。
$jobid = isset($_GET['jobid']) ? $_GET['jobid'] : 0;
//Make sure jobid is specified
if($jobid == 0) { return; }
header("Connection: close");
@ob_end_clean();
ignore_user_abort();
ob_start();
echo 'Launched in backgroud';
$size = ob_get_length();
header("Content-Length: ".$size);
ob_end_flush();
flush();
$_SESSION['job'][$jobid]['currentfile'] = 0;
// 3. When app appove backup,
// - Write infos to DB
// - Zip all files into 1 backup file
$datebackup = time();
$bckpstatus = 1; //In progress
$pathtobackup = $_SESSION['job'][$jobid]['path'];
/*
$query = "INSERT INTO backups (watchID, path, datebackup, checksum, sizeori, sizebackup, bckpcomplete)
VALUES ($watchID, '{$path}', '{$datebackup}', '', '{$files_totalsize}', '', '{$bckpstatus}')";
$sth = $db->prepare($query);
$db->beginTransaction();
$sth->execute();
$db->commit();
$sth->closeCursor();
*/
$backupname = $jobid.".".$GLOBALS["backup_ext"];
$backuplocation = "D:\\";
if( ($fp = popen("7za a -t7z ".$GLOBALS["backup_compression"]." \"".$backuplocation.$backupname."\" \"".$pathtobackup."\"", "r")) ) {
while( !feof($fp) ){
$fread = fread($fp, 256);
$line_array = preg_split('/\n/',$fread);
$num_lines = count($line_array);
$_SESSION['job'][$jobid]['currentfile'] = $_SESSION['job'][$jobid]['currentfile']+$num_lines;
$num_lines = 0;
sleep(1);
flush();
}
pclose($fp);
}