0

可能重复:
php exec 命令(或类似命令)不等待结果
exec() 等待 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 脚本完成运行?

4

2 回答 2

2

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();
}
于 2012-10-29T19:07:46.467 回答
1

我相信如果你改变passthruexec会按预期工作。你也可以试试这个:

$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;
    }

}
于 2012-10-29T18:45:04.823 回答