7

I want to trigger a shell command in eider exec() or system() from PHP script but it is a task that take a while to complete, is there a way to trigger it and continue running the PHP page load without delay?

Edit: I am on CentOS 6, PHP 5.3

adrianTNT
  • 3,671
  • 5
  • 29
  • 35

5 Answers5

17

Depends on the OS you are using.

For linux:

pclose(popen("php somefile.php &","r"));

notice the amperstand at the end (very important).

For windows:

pclose(popen("start php.exe somefile.php","r"));

here the start keyword is important.

Hope this helps.

Eduard Luca
  • 6,514
  • 16
  • 85
  • 137
  • 1
    I tried `exec("php video_processor.php &");` and delay is the same, then also if I set a `sleep(10)` inside video_processor.php then my parent script also waits for 10 seconds. – adrianTNT Jan 18 '12 at 13:00
  • Try with `pclose(popen("php video_processor.php &","r"));` or `pclose(popen("/usr/bin/php video_processor.php &","r"));` (I assume your PHP is installed in the default location) – Eduard Luca Jan 18 '12 at 13:03
  • It worked with this one: `pclose(popen("php video_processor.php &","r"));` so then I edited mine and it worked: `pclose(popen("ffmpeg -i 'videos/sample.mp4' -qmax 1 -vframes 1 -ss 80 videos/images/1.jpg &","r"));` Thank you. :party: :) – adrianTNT Jan 18 '12 at 13:10
  • Wow, I can't believe how easy and simple this is to do! Brilliant solution! I have researched this at some length before and every other solution recommended complex strategies for forking or threading a PHP process. – Matt Korostoff Apr 04 '15 at 20:12
  • 1
    Windows specific comment: I used to use: pclose(popen("start /B php.exe somefile.php","r")); as of Windows 10 Creators Update (1703) - the "/B" background switch for "start" command doesnt work. Glad to see that it isnt needed. – MSC May 10 '17 at 19:46
3

This doesn't answer your question directly, but you should consider doing your video conversion work in a background process with either a cron job or using a queue such as Beanstalkd.

This way you can stack up your ffmpeg work in the background without blocking your webserver.

I've had a lot of success with both methods (cron / queue) in the past.

Some other posts about background processes:

php execute a background process

Run a ffmpeg process in the background

Using ffmpeg, PHP and beanstalk

Some tools you might find useful:

http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/

PEAR System_Daemon

Pheanstalk, a Beanstalkd library for PHP

Community
  • 1
  • 1
Darren Newton
  • 2,847
  • 1
  • 29
  • 31
2

What I do:

public function post_create()
{
    ob_end_clean();
    header("Connection: close");
    ignore_user_abort(); // optional
    ob_start();
    echo "Tell ajax to gtfo!";

    $size = ob_get_length();
    header("Content-Length: $size");
    ob_end_flush(); // Strange behaviour, will not work
    flush();            // Unless both are called !
    // Do processing here
}
Michael J. Calkins
  • 32,082
  • 15
  • 62
  • 91
0

This should work:

shell_exec("nohup yourcommand > /dev/null 2> /dev/null &");

Edit: sorry, dunno why I excluded the & to put it to bg 2> redirects STDOUT and STDERR to /dev/null.

Uku Loskit
  • 40,868
  • 9
  • 92
  • 93
  • Command runs but the delay is there, this is the full command: `shell_exec("ffmpeg -i 'videos/sample.mp4' -qmax 1 -vframes 1 -ss 80 videos/images/1.jpg 2> /dev/null");` – adrianTNT Jan 18 '12 at 12:33
  • try: shell_exec("nohup ffmpeg -i 'videos/sample.mp4' -qmax 1 -vframes 1 -ss 80 videos/images/1.jpg > /dev/null 2> /dev/null") – Uku Loskit Jan 18 '12 at 12:35
  • Same delay, command executed fine. Maybe ffmpeg just acts differently? – adrianTNT Jan 18 '12 at 12:41
  • Just tested this myself with PHP and ffmpeg and now it works. – Uku Loskit Jan 18 '12 at 13:13
-1

Well use an ajax request to activate the exec part ...then continue with the other tasks

poojitha
  • 335
  • 1
  • 3
  • 12