Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous popen exec in PHP on Windows

I am having a strange issue. I recently set up a process on our test servers to call a script asynchronously from another script. It has been working during testing, up until recently. Let me give some of the technical details before proceeding. The call from the originating script looks like this (I have updated the logic that makes the call):

exec('cmd /S /C "'.$command.' 1> nul 2>&1"');

Where $command is created using the following logic:

                $args = array(
                    'php',
                    '"'.getcwd().'{absolute path to a php script}"',
                    escapeshellarg($job_id),
                    escapeshellarg($vhost),
                    escapeshellarg($debug),
                );
                $command = implode(' ', $args);

PHP version is 5.3.10 and the server is a hosted box running Windows Server 2008 R2 Standard.

  • I have verified that php is still in the system path
  • I have used debug output to see that the asynch call is being made, and what args it is being made with -everything still seems to be correct.
  • If I call the command contained in $command manually from the windows system terminal it runs as expected
  • If I run the $command as exec would run it (with 'cmd /S /C' it fails complaining that it cannot open the php script)

What really boggles my mind is that this was working this time last week. I made a few changes to the code (seemingly unrelated) and even after reverting my changes to see if that was the problem - this process is still broken.

At this point I am mystified and would welcome any insight, ideas or help.

like image 284
Dogoferis Avatar asked Mar 21 '23 09:03

Dogoferis


2 Answers

Eventually I was able to simply get around this problem by not using popen or exec at all, it seems like those may be best avoided when using PHP on a Windows platform - if you are trying to create an asynchronous script call that is. Instead I resorted to the Windows COM object support in PHP.

$handle = new COM('WScript.Shell');
$handle->Run($command, 0, false);

This starts the process in the background (hides window/does not open a new window) and executes it asynchronously - i.e. does not wait for it to finish.

Included here is the documentation page for WScript.Shell which gives the official description of the effect(s) of the parameters passed. Although I did not stop to benchmark it, I will say that anecdotally it feels that his process now runs more quickly than it used to when I was trying to use exec/popen/etc.

like image 196
Dogoferis Avatar answered Mar 29 '23 13:03

Dogoferis


Rather than redirecting the output to nul, try redirecting everything to a file. That should tells you if there's a PHP error somewhere:

$outFilePath = "/path/to/file.log";
pclose (popen('start /B cmd /S /C "'.$command.' > ' . $outFilePath . ' 2>' . $outFilePath . ' &"',"r") );

Also is there any reason you are using pclose / popen rather than something more simple like exec?

like image 35
laurent Avatar answered Mar 29 '23 12:03

laurent