【问题标题】:Make PHP wait for Matlab script to finish executing [duplicate]让PHP等待Matlab脚本完成执行[重复]
【发布时间】:2012-10-29 18:29:08
【问题描述】:

可能重复:
php exec command (or similar) to not wait for result
exec() waiting for a response in PHP

我有一个调用和运行 Matlab 脚本的 php 脚本。 Matlab 脚本的结果是一个 .png 图像,然后我想将其加载到 php 中并发送到网页。我的php代码是:

$matlabExe = '"C:\\Program Files\\MATLAB\\R2012a\\bin\\matlab.exe"';
$mFile = "'C:\\processSatData.m'";
$combine = '"run(' . $mFile . ');"';
$command = $matlabExe . ' -nodisplay -nosplash -nodesktop -r ' . $combine;

passthru($command);

$im = file_get_contents('C:\\habitat.png');
header('Content-type:image/png');
echo $im;

但是,似乎在发送“passthru”命令后,php 并没有等待 Matlab 脚本完成运行。因此,如果图像文件在运行 php 代码之前不存在,则会收到错误消息。

有没有办法让 php 代码在尝试加载图像文件之前等待 Matlab 脚本完成运行?

【问题讨论】:

  • 您可以休眠/循环并等待输出图像文件出现。此外,如果 matlab 关闭,您可能可以使用 proc_open 并等待该过程完成:
  • @Dagon 但链接不能解决 OP 问题 ....
  • 第二个链接的标记答案对我来说看起来很完美。
  • OP 想等到程序结束。问题是,它在后台运行(看起来像)。但是为什么passthru我必须问。没有准备好 matlab,所以我无法测试。

标签: php matlab


【解决方案1】:

passthru 不是这里的主要问题 .. 但我想一旦您从命令中得到响应,图像就不会立即写入,而是由第三个进程写入

file_get_contents 在这种情况下也可能会失败,因为 .. 图像可能不会被写入一次或在写入过程中,这可能导致文件锁定 .. 在任何情况下,您都需要确保之前有一个有效的图像输出已发送;

set_time_limit(0);
$timeout = 30; // sec
$output = 'C:\\habitat.png';
$matlabExe = '"C:\\Program Files\\MATLAB\\R2012a\\bin\\matlab.exe"';
$mFile = "'C:\\processSatData.m'";
$combine = '"run(' . $mFile . ');"';
$command = $matlabExe . ' -nodisplay -nosplash -nodesktop -r ' . $combine;

try {
    if (! @unlink($output) && is_file($output))
        throw new Exception("Unable to remove old file");

    passthru($command);

    $start = time();
    while ( true ) {
        // Check if file is readable
        if (is_file($output) && is_readable($output)) {
            $img = @imagecreatefrompng($output);
            // Check if Math Lab is has finished writing to image
            if ($img !== false) {
                header('Content-type:image/png');
                imagepng($img);
                break;
            }
        }

        // Check Timeout
        if ((time() - $start) > $timeout) {
            throw new Exception("Timeout Reached");
            break;
        }
    }
} catch ( Exception $e ) {
    echo $e->getMessage();
}

【讨论】:

  • 这似乎工作得很好。我还尝试了 Anthony 发布的简单 while 循环,虽然由于额外的错误检查,我选择你的作为答案。我仍然有一个问题,即图像没有正确发送回我的 html 页面(它显示的是 ASCII 而不是图像),但这是一个完全独立的问题。谢谢!
  • @Josiah 很高兴我能提供帮助
【解决方案2】:

我相信,如果您将 passthru 更改为 exec,它将按预期工作。你也可以试试这个:

$matlabExe = '"C:\\Program Files\\MATLAB\\R2012a\\bin\\matlab.exe"';
$mFile = "'C:\\processSatData.m'";
$combine = '"run(' . $mFile . ');"';
$command = $matlabExe . ' -nodisplay -nosplash -nodesktop -r ' . $combine;

passthru($command);

// once a second, check for the file, up to 10 seconds
for ($i = 0; $i < 10; $i++) { 
    sleep(1);

    if (false !== ($im = @file_get_contents('C:\\habitat.png'))) {
        header('Content-type:image/png');
        echo $im;
        break;
    }

}

【讨论】:

  • 我认为你需要修改while循环条件。
  • 我尝试将 passthru 更改为 exec,但它仍然给我一个错误。但是,检查文件的循环可能会起作用。我会试一试。谢谢。
  • 大声笑,是的,那更好@setsuna,谢谢
猜你喜欢
  • 2016-05-23
  • 1970-01-01
  • 2012-07-16
  • 1970-01-01
  • 1970-01-01
  • 2013-02-17
  • 2011-05-22
  • 1970-01-01
相关资源
最近更新 更多