I have always used:
$pid = exec(\"/usr/local/bin/php file.php $args > /dev/null & echo \\$!\");
But I am using an XP virtual machine to
I landed here thanks to google and decided that this ten years old post needs more info based on How to invoke/start a Process in PHP and kill it using Process ID...
Imagine that you want to execute a command (this example uses ffmpeg to stream a file on a windows system to a rtmp server). You could command something like this:
ffmpeg -re -i D:\wicked_video.mkv -c:v libx264 -preset veryfast -b:v 200k -maxrate 400k -bufsize 6000k -pix_fmt yuv420p -g 50 -c:a aac -b:a 160k -ac 2 -ar 44100 -f flv rtmp://<IP_OF_RMTP_SERVER>/superawesomestreamkey > d:\demo.txt 2> d:\demoerr.txt
The first part is explained here and the last part of that command outputs to files with that name for logging purposes:
> d:\demo.txt 2> d:\demoerr.txt
So lets assume that that command works. You tested it. To run that command with php you can execute it with exec but it will take time (another subject, check set_time_limit), its a video handled by ffmpeg via php. Not the way to go but it is happening in this case.
You can run the command in background but what is the pid of that Process? We want to kill it for some reason and psexec gives only the 'process ID" runned by a user. And there is only one user in this case. We want multiple processes on the same user.
Here is a example to get the pid of a runned process in php:
// the command could be anything:
// $cmd = 'whoami';
// This is a f* one, The point is: exec is nasty.
// $cmd = 'shutdown -r -t 0'; //
// but this is the ffmpeg example that outputs seperate files for sake
$cmd = 'ffmpeg -re -i D:\wicked_video.mkv -c:v libx264 -preset veryfast -b:v 200k -maxrate 400k -bufsize 6000k -pix_fmt yuv420p -g 50 -c:a aac -b:a 160k -ac 2 -ar 44100 -f flv rtmp://10.237.1.8/show/streamkey1 > d:\demo.txt 2> d:\demoerr.txt';
// we assume the os is windows, pipe read and write
$descriptorspec = [
0 => ["pipe", "r"],
1 => ["pipe", "w"],
];
// start task in background, when its a recource, you can get Parent process id
if ( $prog = is_resource( proc_open("start /b " . $cmd, $descriptorspec, $pipes ) ) )
{
// Get Parent process Id
$ppid = proc_get_status($prog);
// this is the 'child' pid
$pid = $ppid['pid'];
// use wmic to get the PID
$output = array_filter( explode(" ", shell_exec("wmic process get parentprocessid,processid | find \"$pid\"" ) ) );
array_pop($output);
// if pid exitst this will not be empty
$pid = end($output);
// outputs the PID of the process
echo $pid;
}
The code above should echo the pid of the 'inBackground' runned process.
Note that you need to save the pid to kill it later if it is still running.
Now you can do this to kill the process: (imagine the pid is 1234)
//'F' to Force kill a process
exec("taskkill /pid 1234 /F");
Here is my first post ever here on stackoverflow, I hope this will help someone. Have a awesome and not lonely christmas ♪♪
Here's a somewhat less "hacky" version of SeanDowney's answer.
PsExec returns the PID of the spawned process as its integer exit code. So all you need is this:
<?php
function spawn($script)
{
@exec('psexec -accepteula -d php.exe ' . $script . ' 2>&1', $output, $pid);
return $pid;
} // spawn
echo spawn('phpinfo.php');
?>
The -accepteula argument is needed only the first time you run PsExec, but if you're distributing your program, each user will be running it for the first time, and it doesn't hurt anything to leave it in for each subsequent execution.
PSTools is a quick and easy install (just unzip PSTools somewhere and add its folder to your path), so there's no good reason not to use this method.
You will have to install an extra extension, but found the solution located at Uniformserver's Wiki.
UPDATE
After some searching you might look into tasklist
which coincidently, you may be able to use with the PHP exec
command to get what you are after.
I'm using Pstools which allows you to create a process in the background and capture it's pid:
// use psexec to start in background, pipe stderr to stdout to capture pid
exec("psexec -d $command 2>&1", $output);
// capture pid on the 6th line
preg_match('/ID (\d+)/', $output[5], $matches);
$pid = $matches[1];
It's a little hacky, but it gets the job done