0

Possible Duplicate:
php exec command (or similar) to not wait for result
exec() waiting for a response in PHP

I have a php script that calls and runs a Matlab script. The result of the Matlab script is a .png image, which I would then like to load in php and send to a webpage. The php code I have is:

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

However, it appears that after sending the 'passthru' command, php does not wait for the Matlab script to finish running. Thus, if the image file does not exist before running the php code, then I get an error message.

Is there a way to make it so that the php code waits for the Matlab script to finish running before it attempts to load the image file?

Community
  • 1
  • 1
Josiah
  • 654
  • 2
  • 13
  • 25
  • You could sleep/loop and wait for the output image file to appear. Also if matlab closes, you could probably use [proc_open](http://php.net/proc_open) and wait until the process has finished: – hakre Oct 29 '12 at 18:40
  • wrong one should of been: http://stackoverflow.com/questions/7093510/exec-waiting-for-a-response-in-php –  Oct 29 '12 at 18:42
  • @Dagon but links do not solve OP questions .... – Baba Oct 29 '12 at 18:44
  • marked answer to 2nd link looks perfect to me. –  Oct 29 '12 at 18:45
  • OP wants to wait until the program has finsihed. Problem is, that it is running in the background (as it looks like). However why `passthru` I must ask. Not having matlab ready so I can not test. – hakre Oct 29 '12 at 18:45
  • Dagon ... looks but solves naaa .. ran a simulation and that does not fix the issue.. hakre has a perfect solution i wonder why no answer yet – Baba Oct 29 '12 at 18:46
  • I'll give the sleep/loop idea a go. I imagine that will work just fine. Not quite sure how the proc_open function works, though. I've only been messing around with php for a couple days now, so have much to learn. Thanks. – Josiah Oct 29 '12 at 19:09

2 Answers2

2

passthru is not the main issue here .. but i guess as soon you have a response from your command the image is not written instantly but by a 3rd process

file_get_contents might also fail in this instance because .. The image might not be written once or in the process of writing which can result to file lock .. in any case you need to be sure you have a valid image before output is sent;

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();
}
Baba
  • 94,024
  • 28
  • 166
  • 217
  • 1
    This seems to work just fine. I also tried the simple while loop posted by Anthony, which worked, although I'm selecting yours as the answer due to the extra error checking. I still have an issue where the image isn't being correctly sent back to my html page (it's displaying ASCII and not the image), but that's a whole separate issue. Thanks! – Josiah Oct 29 '12 at 19:24
  • @Josiah glad i was able to help – Baba Oct 29 '12 at 19:25
1

I believe if you change passthru to exec it will work as intended. You can also try this:

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

}
georgepsarakis
  • 1,927
  • 3
  • 20
  • 24
Anthony Hatzopoulos
  • 10,437
  • 2
  • 40
  • 57