How to debug popen() not working? - php

On my Linux server I use shell_exec() to run scripts asynchronously. This function is not available on Windows, which I use for development, and so I am trying to use popen() instead.
I am running Windows 10 x64, WampServer 2.5 x32 (PHP 5.5.12).
I have the following code in a PHP file:
$cmd = '"C:\wamp\bin\php\php5.5.12\php.exe" "C:\wamp\www\path\to\file.php" "arg1" "arg2"';
echo 'Running on DEV MACHINE: ' . $cmd . PHP_EOL;
$handle = popen("start /B " . $cmd, "r");
if ($handle === FALSE) {
die("Unable to execute $cmd");
}
pclose($handle);
The script executes without any errors, but the PHP files are never run. I know they aren't being run because I put an SQL query at the very top to update a field in a database to indicate they have been run.
As you can see in the above code, I print out the command being passed to popen(). If I paste that command into command prompt and execute it, the scripts run fine. This proves the issue lies with popen().
Am I using popen() incorrectly somehow? How can I debug what the problem is? Normally I would debug using XDebug, but there's no way to use that in this situation.

I was never able to get my code working, but I found an alternative method from another answer on here and based on that changed my code to use the following and it works:
$WshShell = new \COM("WScript.Shell");
$oExec = $WshShell->Run($cmd, 0, false);

Related

PHP misses system variables when using exec

So i have a project where I send spotify track URL to server and store it. I use laragon with PHP 7.4 installed, windows 11. I use that downloader. It works via cmd command line. When I try to use it by hand it works fine, but when i send it by exec() it doesn't work. I can't get any return message neither. I have tried using exec(), system() and shell_exec() functions. The problem might be with with system variables, as these might not be visible for PHP. I have also tried turning on/off server and it didn't work. I have also tried to put putenv('PATH=' . $_SERVER['PATH']) at the beginning of file. I tried to check laragon path variables itself - I couldn't see these i have added. Any other default windows commands works as should be. Any ideas on how to fix it?
Here is my PHP code:
function createFile($url, $token){
function execCommand($dir, $url){
$command1 = "cd $dir";
$command2 = "spotdl $url";
if(!shell_exec($command1. "&& ". $command2)) return false;
return true;
}
$path = "C:\Laragon/laragon/www/temp/";
$dir = $path.$token.'/';
if(!mkdir($dir, 0777)) throwError("Server error");
if(!execCommand($dir, $url)) return false;
return true;
}
I know i'm not returning any output from console, but that is post updates. Second command is definitely beeing called, i have tested it on some other commands (like mkdir)
In many os the errors output (stderr) of the commands isn't the same that the normal output (stdout), you need to redirect the errors to the stdout. so the command must be:
$ command $arg1 $arg2 ... 2>&1
This cause that the errors messages will be sent to the stdout, Is util remember this when you are working with system calls.
Now in your code i prefer to use the exec function in php
<?php
$result = 0;
$output = [];
$command = "your command with the 2>&1";
exec($command, $output, $result);
if ($result != 0) {
// here an error ocurred and you can see the error on the ouput array
exit();
}
// here you know that the command was executed successfully
After re-installing laragon it worked. I Have checked before uninstalling path variables and i haven't seen mine that should be in.
I couldn't modify it either so I just reinstalled it.

php exec or shell_exec not terminating its process after script execution ends in linux

I am trying to check for syntax error of a php file using shell commands, its working fine in Windows (WAMP) but on linux the process created by shell commands exec/shell_exec/popen etc never terminates thus causing apache to hang while this process gets forcefully killed by me. also no output is generated after killing the process.
my test script is
file test.php is sample one line php file for testing only which contains
<?php
$test['arr'] = 'bla';
?>
and the code by which i try to check syntax error is:
$slash = file_get_contents('test.php');
$tmpfname = tempnam("tmp", "PHPFile");
file_put_contents($tmpfname, $slash);
exec("php -l ".$tmpfname." 2>&1",$error); //also tried shell_exec but same behaviour
$errtext = '';
foreach($error as $errline) $errtext.='<br>'.$errline;
unlink($tmpfname);
echo $errtext;
also tried using function popen
$slash = file_get_contents('test.php');
$tmpfname = tempnam("tmp", "PHPFile");
file_put_contents($tmpfname, $slash);
$handle = popen("php -l ".$tmpfname." 2>&1", 'r');
$errtext = fread($handle, 2096);
pclose($handle);
unlink($tmpfname);
echo $errtext;
please someone point me where i am doing wrong and why process created by shell commands never ends itself in linux, i tried searching lot about this problem but i get no result.
I got the root cause of the blocking issue, It was php session which was blocking all other requests in linux server from the same user (surprisingly on windows it works well).
I used session_write_close(); before running exec and problem resolved, but now i have one another problem with this script in linux, it is posted in another question php exec/shell_exec/system/popen/proc_open runs calling script itself infinite number of times on linux

PHP exec to run a file

I am trying for last 3 hours to tell PHP to run a simple file. I am using wamp server for windows in local host (Windows 8)
I've tried with exec() working with:
echo exec('whoami');
I got response nt authority.
Also tested with:
if(function_exists('exec')) {
echo "exec is enabled";
}
So it probably works?
I am trying to run a file called tester.php
When I include it, its working, when I require it its working. I need to execute it in background. When I refresh file, code is working without any error, it writes to the database normally.
When i try to exec it its not working.
I tried :
exec("php http://localhost/diplomski/program/defender/tester.php");
exec("php-cli http://localhost/diplomski/program/defender/tester.php");
exec("http://localhost/diplomski/program/defender/tester.php");
Not working, also tried:
exec("php http://127.0.0.1/diplomski/program/defender/tester.php");
exec("php-cli http://127.0.0.1/diplomski/program/defender/tester.php");
exec("php-cli d:\wamp\www\diplomski\program\defender/tester.php")
Not working also tried:
exec("php tester.php");
exec("php-cli tester.php");
exec("tester.php");
Also tried:
$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("D:\wamp\bin\php\php5.3.13\php-win.exe -f d:\wamp \www\diplomski\program\defender/tester.php", 0, false);
Tried this, its refreshing infinitely and not working:
exec("php d:\wamp\www\diplomski\program\defender/tester.php");
exec("php-cli d:\wamp\www\diplomski\program\defender/tester.php");
exec("d:\wamp\www\diplomski\program\defender/tester.php");
I'm starting to pull my hair out here. First time I'm trying to use exec() and I'm not very good with it or with the commands.
Give the full path to the PHP executable and the full path to the PHP script. You can save the output in $output to see what the script produced:
exec("d:/path/to/php.exe d:/wamp/www/diplomski/program/defender/tester.php", $output);
print_r($output);
1) What version of php? If it is older then 5.4.0 php can be in safe mode, when safe mode is enabled, you can only execute files within the safe_mode_exec_dir.
2)Note to this function in php.net
Note:
If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.
3) So you can try this How to make php script run another php script you can try this
<?php
$somearg = escapeshellarg('blah');
exec("php file2.php $somearg > /dev/null &");
4) You can create a scheduled task How to run a PHP file in a scheduled task (Windows Task Scheduler)
In addition to the earlier answers, let me add that if you want to execute a PHP file from within PHP, you may want to consider the PHP function include instead:
include $path."tester.php"
I guess that would be (much?) more efficient than to spawn a new shell which executes a new instance of PHP which executes the file. But of course the choice of the "better option" may depend on the context.

Windows PHP exec / shell_exec with phantomjs always returns null

I'm running PHP 5.4.9 on Windows server
I've tried running all script commands in PHP (exec, shell_exec, system, proc_open, passthru). All seem to return empty or null.
I've added phantomjs as a PATH variable.
And running phantomjs --version in command prompt, and it returns 1.8.2
Although when I try to run
$return = exec("phantomjs --version")
or
$return = shell_exec("phantomjs --version", $output)
$return is always null and $output is empty.
I made sure IUSR and IIS_IUSRS users have permission to run phantomjs.exe
Safe mode is disabled in php.ini
Also, I tried running exec('ls') && exec('ipconfig /all'), and those output the data I'm expecting.
I'm not sure what else to try.
I was facing the same problem..
The thing is phantomjs requires complete path for all
Here is the solution I came up with:
$getout = exec('D:\\xampp\\htdocs\\phantomjsdir\\phantomjs.exe D:\\xampp\\htdocs\\rasterisejsdir\\rasterize.js http://localhost/pagetobecaptured/test D:\\xampp\\htdocs\\outputfiledir\\test2.jpg "1800px*840px"',$o,$e);
You are pretty close to a solution. It's basically:
$stdout = shell_exec('time /T');
echo $stdout;
You need to make sure, that the Phantom binary is either on path or called with full-path.
For a full example executing PhantomJS, see the driver file of "jakoch/PHPUnit-headless".

PHP on a windows machine; Start process in background

I'm looking for the best, or any way really to start a process from php in the background so I can kill it later in the script.
Right now, I'm using: shell_exec($Command);
The problem with this is it waits for the program to close.
I want something that will have the same effect as nohup when I execute the shell command. This will allow me to run the process in the background, so that later in the script it can be closed. I need to close it because this script will run on a regular basis and the program can't be open when this runs.
I've thought of generating a .bat file to run the command in the background, but even then, how do I kill the process later?
The code I've seen for linux is:
$PID = shell_exec("nohup $Command > /dev/null & echo $!");
// Later on to kill it
exec("kill -KILL $PID");
EDIT: Turns out I don't need to kill the process
shell_exec('start /B "C:\Path\to\program.exe"');
The /B parameter is key here.
I can't seem to find where I found this anymore. But this works for me.
Will this function from the PHP Manual help?
function runAsynchronously($path,$arguments) {
$WshShell = new COM("WScript.Shell");
$oShellLink = $WshShell->CreateShortcut("temp.lnk");
$oShellLink->TargetPath = $path;
$oShellLink->Arguments = $arguments;
$oShellLink->WorkingDirectory = dirname($path);
$oShellLink->WindowStyle = 1;
$oShellLink->Save();
$oExec = $WshShell->Run("temp.lnk", 7, false);
unset($WshShell,$oShellLink,$oExec);
unlink("temp.lnk");
}
Tried to achieve the same on a Windows 2000 server with PHP 5.2.8.
None of the solutions worked for me. PHP kept waiting for the response.
Found the solution to be :
$cmd = "E:\PHP_folder_path\php.exe E:\some_folder_path\backgroundProcess.php";
pclose(popen("start /B ". $cmd, "a")); // mode = "a" since I had some logs to edit
From the php manual for exec:
If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.
ie pipe the output into a file and php won't wait for it:
exec('myprog > output.txt');
From memory, I believe there is a control character that you can prepend (like you do with #) to the exec family of commands that also prevents execution from pausing - can't remember what it is though.
Edit Found it! On unix, programs executed with & prepended will run in the background. Sorry, doesn't help you much.
On my Windows 10 and Windows Server 2012 machines, the only solution that worked reliably within pclose/popen was to invoke powershell's Start-Process command, as in:
pclose(popen('powershell.exe "Start-Process foo.bat -WindowStyle Hidden"','r'));
Or more verbosely if you want to supply arguments and redirect outputs:
pclose(popen('powershell.exe "Start-Process foo.bat
-ArgumentList \'bar\',\'bat\'
-WindowStyle Hidden
-RedirectStandardOutput \'.\\console.out\'
-RedirectStandardError \'.\\console.err\'"','r'));

Categories