1

I have a problem with shell_exec. I try to run the other php file in a separate thread, according to this answer: https://stackoverflow.com/a/222445/1999929 I have this very-very simple code:

<?php
     $realpath = realpath("./second.php");
     file_put_contents("./log.txt","\nFirst php running!\n",FILE_APPEND);
     shell_exec("php $realpath > /dev/null 2>/dev/null &");
?>

I need this because i want to use this file for a dropbox webhook link, and it has to give a response in 10 seconds, while processing the changed files sometimes takes more time. So this file has to tell te other to run, and give a response, while not waiting for the other to finish.

When shell_exec is used in the code, the text is outputted infinite times in the file, without it its working fine, but i need to call the other file somehow.

EDIT - I tried exec() too, because the answer above used it instead of shell_exec, results are the same.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Koocka
  • 111
  • 1
  • 3
  • 9
  • You mean it's writing `First php running` many times? That can only mean that your script is running many time. There is no way that this code will loop by itself. – Barmar Aug 22 '14 at 00:23
  • Does `second.php` have an `include` or `require` line that loads this script? That will cause repetition. – Barmar Aug 22 '14 at 00:24
  • There is just debug code in second.php yet, no includes requires or anything. It is writing "First php running" in an infinte loop to the file. It is nonsense to me, too, thats why im asking here :) EDIT - and one more important thing: second.php wont run. – Koocka Aug 22 '14 at 00:48
  • What happens if you comment out the `shell_exec` line, do you still get the repeats? – Barmar Aug 22 '14 at 00:51
  • Nope, i tried that. if i comment out shell_exec, it writes 1 line to the file. I thought of a webhooks failure too, but it works fine. – Koocka Aug 22 '14 at 00:52
  • What happens if you run it without `&`? – Barmar Aug 22 '14 at 00:54
  • The line is outputted exactly 30 times, and i get a php warning: [22-Aug-2014 01:26:01 CET] PHP Warning: shell_exec(): Unable to execute 'php second.php' in .../first.php on line 30 – Koocka Aug 22 '14 at 01:00
  • Maybe `php` isn't in the server's `$PATH`. Try using the full path to the `php` executable. – Barmar Aug 22 '14 at 01:03
  • You, sir, won. I replaced php with PHP_BASEDIR/php , and works like a charm. Thanks for your help! :) – Koocka Aug 22 '14 at 01:12
  • I still don't see how that caused all the repetitions. Do you have error handling around this that retries failures? Does it also work correctly when you run it in the background with `&`? – Barmar Aug 22 '14 at 01:26
  • Im on a shared host, so i dont know anything about error handling. I added the &, and it works fine too. – Koocka Aug 22 '14 at 01:30
  • I meant something like `try/catch` in the PHP script. – Barmar Aug 22 '14 at 01:31
  • Nothing. The code is that 5 lines, that i pasted in the question. – Koocka Aug 22 '14 at 01:36
  • The error message said `line 30`, so it's more than 8 lines. – Barmar Aug 22 '14 at 01:37
  • Tried to save it to phpfiddle, but couldnt because shell_exec and file write is disabled, and i ran out of the edit time limit, sorry. anyway, with the 8 line code it gives the same error, in line 8 ( the line of exec ) – Koocka Aug 22 '14 at 02:02

2 Answers2

1

The issue is with the ENV, something in the ENV conflict with the second call to PHP making PHP calling infinite times the second file. This will create a fork bomb.

But if you just reset the $env array to an empty array the second file will be called correctly.

Neither shell_exec() or exec() all you to manipulate $ENV. You'll need to use "proc_open":

resource proc_open ( $cmd , $descriptorspec , &$pipes [, $cwd [, $env]] )

So:

<?php
     $env = array();
     $realpath = realpath("./second.php");
     file_put_contents("./log.txt","\nFirst php running!\n",FILE_APPEND);
     proc_open(
        "php $realpath > /dev/null 2>/dev/null &",
        $descriptorspec,
        $pipes,
        __DIR__,
        $env
     );
?>
Max Cuttins
  • 614
  • 2
  • 6
  • 20
0

This bug affect only the CGI version of PHP, the CGI module replace the command called with the script itself causing infinite loop.

In order to prevent this you should call "php-cli" instead of "php":

shell_exec("php-cli $realpath > /dev/null 2>/dev/null &");
Max Cuttins
  • 614
  • 2
  • 6
  • 20