php执行后台进程

时间:2020-03-05 18:48:16  来源:igfitidea点击:

我需要根据用户操作执行目录副本,但是目录很大,因此我希望能够执行这样的操作,而用户却不知道完成副本所花费的时间。

任何建议将不胜感激。

解决方案

回答

我们可以安排一个单独的过程,然后在后台运行副本吗?自从我编写了PHP已经有一段时间了,但是功能pcntl-fork看起来很有希望。

回答

假设它在Linux机器上运行,我总是这样处理:

exec(sprintf("%s > %s 2>&1 & echo $! >> %s", $cmd, $outputfile, $pidfile));

这将启动命令$ cmd,将命令输出重定向到$ outputfile,并将进程ID写入$ pidfile。

这样一来,我们可以轻松地监视该进程正在执行的操作以及它是否仍在运行。

function isRunning($pid){
    try{
        $result = shell_exec(sprintf("ps %d", $pid));
        if( count(preg_split("/\n/", $result)) > 2){
            return true;
        }
    }catch(Exception $e){}

    return false;
}

回答

使用方便的任何语言(php / bash / perl / etc)将过程编写为服务器端脚本,然后从php脚本中的过程控制功能调用它。

该函数可能会检测标准io是否用作输出流,如果是,它将设置返回值。如果没有,则结束

Proc_Close (Proc_Open ("./command --foo=1 &", Array (), $foo));

我使用" sleep 25s"作为命令从命令行快速进行了测试,它的工作原理很吸引人。

(在这里找到答案)

回答

我只想添加一个非常简单的示例,以在Windows上测试此功能:

创建以下两个文件并将其保存到Web目录:

前景色.php:

<?php

ini_set("display_errors",1);
error_reporting(E_ALL);

echo "<pre>loading page</pre>";

function run_background_process()
{
    file_put_contents("testprocesses.php","foreground start time = " . time() . "\n");
    echo "<pre>  foreground start time = " . time() . "</pre>";

    // output from the command must be redirected to a file or another output stream 
    // http://ca.php.net/manual/en/function.exec.php

    exec("php background.php > testoutput.php 2>&1 & echo $!", $output);

    echo "<pre>  foreground end time = " . time() . "</pre>";
    file_put_contents("testprocesses.php","foreground end time = " . time() . "\n", FILE_APPEND);
    return $output;
}

echo "<pre>calling run_background_process</pre>";

$output = run_background_process();

echo "<pre>output = "; print_r($output); echo "</pre>";
echo "<pre>end of page</pre>";
?>

background.php:

<?
file_put_contents("testprocesses.php","background start time = " . time() . "\n", FILE_APPEND);
sleep(10);
file_put_contents("testprocesses.php","background end time = " . time() . "\n", FILE_APPEND);
?>

授予IUSR权限以写入我们在其中创建上述文件的目录

授予IUSR权限以读取和执行C:\ Windows \ System32 \ cmd.exe

从网络浏览器中命中foreground.php

应使用输出数组中的当前时间戳和本地资源将以下内容呈现给浏览器:

loading page
calling run_background_process
  foreground start time = 1266003600
  foreground end time = 1266003600
output = Array
(
    [0] => 15010
)
end of page

我们应该在保存上述文件的同一目录中看到testoutput.php,并且应该为空

我们应该在与保存上述文件相同的目录中看到testprocesses.php,并且其中应包含带有当前时间戳记的以下文本:

foreground start time = 1266003600
foreground end time = 1266003600
background start time = 1266003600
background end time = 1266003610