PHP - Windows后台命令工作但仍在等待后台进程完成

时间:2013-11-27 13:45:59

标签: javascript php ajax background pclose

我已尝试过NUMEROUS方法从另一个php脚本启动后台PHP脚本。我需要创建一个数据库文件的zip文件供下载。我已将其设置为立即下载单个文件,但如果文件需要压缩,我希望启动后台进程,将通过电子邮件发送到zip文件的链接。该过程有效,但原始脚本仍在等待该过程完成。我尝试过以下方法,就像我说的那样,它们可以工作,但是他们不会去后台。它让我等待超过八分钟的某些实例(大文件拉链),没有用户会等待它。

print `php -f zipfiles7.php | at now`;

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("C:\wamp\bin\php\php5.4.3\php.exe -f C:/wamp/www/zipfiles7.php", 0, false);

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("cmd /c C:\wamp\bin\php\php5.4.3\php.exe -f C:/wamp/www/zipfiles7.php", 3, false);

$exe = "C:\wamp\bin\php\php5.4.3\php.exe";
$args = "C:\wamp\www\zipfiles7.php";
pclose(popen("start \"bla\" \"" . $exe . "\" " . escapeshellarg($args), "r"));

$cmd = "php-win.exe zipfiles7.php";
$cmd = "start /B php-win.exe zipfiles7.php";
$PID = shell_exec("nohup $cmd > test.txt 2>&1");

exec("Psexec.exe -i -d  php.exe zipfiles7.php");

$cmd = "C:\wamp\bin\php\php5.4.3\php-win.exe -f C:\wamp\www\zipfiles7.php";
function _exec($cmd)
{
    $WshShell = new COM("WScript.Shell");
    $oExec = $WshShell->Run($cmd, 0,false);
    echo $cmd;
    return $oExec == 0 ? true : false;
}_exec("C:\wamp\bin\php\php5.4.3\php-win.exe -f C:\wamp\www\zipfiles7.php");

$cmd = "C:\wamp\bin\php\php5.4.3\php-win.exe -f C:\wamp\www\zipfiles7.php";
pclose(popen('start /B ' . $cmd, 'r'));

$cmd = "C:\wamp\bin\php\php5.4.3\php-win.exe -f C:\wamp\www\zipfiles7.php";
pclose(popen("start /B " . $cmd, "r"));

system("cmd /c php zipfiles7.php > test.txt 2>&1");

exec('psexec start /B -d php.exe zipfiles7.php > test.txt 2>&1');

exec('psexec -d php.exe zipfiles7.php > test.txt 2>&1');

exec('psexec -d php.exe zipfiles7.php');

$cmd = "C:\wamp\bin\php\php5.4.3\php-win.exe -f C:\wamp\www\zipfiles7.php";
exec(sprintf("%s > %s 2>&1 & echo $! >> %s", $cmd, "test.txt", "php_error.log"));

pclose(popen('start /B php zipfiles7.php > test.txt 2>&1', 'r'));

pclose(popen("start /B C:\wamp\bin\php\php5.4.3\php-win.exe -f C:\wamp\www\zipfiles7.php", "r"));

shell_exec('start /B "C:\wamp\bin\php\php5.4.3\php.exe -f C:\wamp\www\zipfiles7.php > test.txt 2>&1"');

exec('START /B "C:\wamp\bin\php\php5.4.3\php.exe -f C:\wamp\www\zipfiles7.php"', $output);

passthru("start /B c:/wamp/bin/php/php5.4.3/php-win c:/wamp/www/zipfiles7.php > test.txt 2>&1");

exec("php.exe -f zipfiles7.php > test.txt 2>&1");

exec("php-win -f zipfiles7.php > /dell/null 2>/dev/null &", $output);

exec("start /B php zipfiles7.php > test.txt 2>&1");

exec("start php.exe -f zipfiles7.php > test.txt 2>&1");

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("cmd /C C:\wamp\www\batch.bat", 0, false);

exec("CHP.exe C:\wamp\www\batch.bat > test.txt 2>&1");

exec("start /min php zipfiles7.php > test.txt 2>&1");

shell_exec('call "cmd /c batch.bat"'); 

batch.bat

@echo off 
"start /B bg C:\wamp\bin\php\php5.4.3\php.exe -f C:\wamp\www\zipfiles7.php > test.txt"

尝试了其他方法:

$descriptorspec = array(
        0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
        1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
        2 => array("pipe", "r") // stderr is a file to write to
    );

    $cmd = "start /B php.exe zipfiles7.php";
    $process = proc_open($cmd, $descriptorspec, $pipes, null, null);
    if (is_resource($process))
    { ....

// buffer all upcoming output
ob_start();
// get the size of the output
$size = ob_get_length();

// send headers to tell the browser to close the connection
header("Content-Length: $size");
header('Connection: close');

// flush all output
ob_end_flush();
ob_flush();
flush();

// close current session
if (session_id()) session_write_close();
    exec("start /B php zipfiles7.php > test.txt 2>&1");

shell_exec('psexec -s -d php.exe zipfiles7.php');

$runCommand = 'php -q zipfiles7.php';
    $WshShell = new COM(“WScript.Shell”);
    $oExec = $WshShell->Run($runCommand, 7, false);

即使尝试JavaScript

function background(){
var url = "C:\wamp\www\zipfiles7.php";// No question mark needed

xmlReq=new XMLHttpRequest();

xmlReq.open("POST",url,true);
xmlReq.send();
console.log("done");
}
echo '<script type="text/javascript">', 'background();', '</script>';

function background(){
var str = "Success";
var url = "C:\wamp\www\zipfiles7.php";

xmlReq=new XMLHttpRequest();

xmlReq.open("POST",url,true);
xmlReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlReq.setRequestHeader("Content-length", str.length);
xmlReq.setRequestHeader("Connection", "close");
xmlReq.send();
console.log("done");
}

即使是Ajax也不会落后于后台!

function background()
{
$.ajax(
    {
           type: "POST",
           url: "zipfiles7.php",
           data: data, // data to send to above script page if any
           cache: false,

           success: function(response)
           {
                alert('Succes');
           }
     });
}

请帮助我理解为什么这个过程不会落到后台。提前谢谢。

1 个答案:

答案 0 :(得分:0)

当你调用exec时,php会暂停执行当前脚本,直到它从shell获取返回值(来自exec)。因此,在这种情况下,php将不会继续执行脚本,直到文件完成压缩。

From the php exec() documentation page:

  

如果程序是使用此功能启动的,则为了它   继续在后台运行,程序的输出必须是   重定向到文件或其他输出流。没有这样做会   导致PHP挂起,直到程序执行结束。

至于以正确的方式实现这一点,我实际上从来没有必须这样做,所以我不能确切地说,但我希望这能指出你正确的方向。

修改:Upon searching a little further I found this stackoverflow answer which seems like it applies to your current question.

相关问题