0

I have to execute a php script (a.php) in the background. I tried this but it's not working:

<?
$cmd = "php /home/megad404/www/prove/a.php &> /dev/null &";
exec('/bin/bash -c "'.$cmd.'"',$output,$return);
if($return===0)
{
    echo 'Successful';
} 
else
{
    echo 'Unsuccessful';
}
?>

It returns "Successful" but it doesn't execute a.php

a.php:

<?
file_put_contents(date("s"),"");
sleep(5);
file_put_contents(date("s"),"");
sleep(5);
file_put_contents(date("s"),"");
?>

a.php writes a file every 5 second and it works fine, except if I try to execute it in the background with the first script.

3 Answers3

1

You can try adapt mi script. Look a command shell_exec() not exec(). First return all , second only last line.

function run_in_background($Command, $Priority = 0) {
         if($Priority)
             $PID = shell_exec("nohup nice -n $Priority $Command > /dev/null & echo $!");
         else
             $PID = shell_exec("nohup $Command > /dev/null & echo $!");
         return($PID);
 }
     //Verifies if a process is running in linux
function is_process_running($PID) {
         exec("ps $PID", $ProcessState);
         return(count($ProcessState) >= 2);
}

and example

$PIDPHP=run_in_background("php -S 127.0.0.1:18086 ".__DIR__."/index.php"); // or any other process.

if (is_process_running($PIDPHP)){
    exec("kill $PIDPHP");
}
ydk2
  • 112
  • 4
0

This just worked for me:

<?php

$cmd = "/usr/bin/php /home/auser/a.php &> /dev/null &";
exec($cmd,$output,$return);
sleep(30);
if($return===0)
{
    echo 'Successful';
} 
else
{
    echo 'Unsuccessful';
}
?>

I saved it as runa.php and ran it from the command window as php runa.php. It produced 3 files.

running a.php also worked from the cron job:

]$ crontab -l
18 * * * * /usr/bin/php /home/auser/a.php

I put the script in a web directory and find that I have some writing problems. What can you see in the server log?

sudo tail -f /var/log/httpd/error_log

And what if you hit a.php from the web browser? Because you mention the script is 755, but how about the directory. Maybe it needs to be 775 or 777 for testing so that the script can write a file?

For testing I created a sub directory "output" and changed a.php

<?php
ini_set('date.timezone','America/New_York'); //without this it makes extra messages

error_log("a.php putting contents", 0);
file_put_contents("output/".date("s"),"");
sleep(5);
file_put_contents("output/".date("s"),"");
sleep(5);
file_put_contents("output/".date("s"),"");
error_log("a.php done", 0);
?>

It was unable to write files until I gave write permission to the ouput folder

sudo chmod 777 /var/www/html/output

Then I found out the apache user is writing the files:

~]$ sudo ls -l /var/www/html/output/
total 0
-rw-r--r--. 1 apache apache 0 Apr 18 11:38 00
-rw-r--r--. 1 apache apache 0 Apr 18 11:38 05
-rw-r--r--. 1 apache apache 0 Apr 18 11:37 55

So I changed the owner of output, in order to tone down the permissiosn again.

~]$ sudo ls -lu /var/www/html/ | grep output
drwxr-xr-x. 2 apache root 4096 Apr 18 12:21 output

This also works now:

 ~]$ sudo ls -l /var/www/html/output
total 0
-rw-r--r--. 1 apache apache 0 Apr 18 12:21 44
-rw-r--r--. 1 apache apache 0 Apr 18 12:21 49
-rw-r--r--. 1 apache apache 0 Apr 18 11:37 55
ndasusers
  • 727
  • 6
  • 12
0

You could also look into using real Posix/PCNTL functionality to actually detach the script to background, eg. with pcntl_exec and pcntl_fork(). This is after my opinion the right way to handle background scripts that runs for a longer period of time as you can communicate with the child/process to get updates, status and so on and even have them understand real signal handling.

PCNTL - http://www.php.net/manual/en/book.pcntl.php

POSIX - http://www.php.net/manual/en/book.posix.php

Cheers

davidbl
  • 175
  • 6