Search code examples
phpajaxffmpegexecshell-exec

I need a to keep a PHP process running in background even If I redirect to another URL


I have a PHP App that execute FFMPEG commands to encode videos and then upload encoded video to YouTube using Youtube v3 API.

I'm using shell_exec to perform FFMPEG actions and works very well.The problem it's that I use an AJAX call to start the whole process and I need to keep the user in the the page where I execute the AJAX call, my intention is execute the AJAX call to start the whole process and inmediatly redirect the user to another page, The problem is that when I redirect to another page the PHP process is interrumped, there are any form to execute AJAX call, redirect and keep the PHP process running in background?


Solution

  • This can be achieved by running the command in your shell_exec in the background. This allows your PHP process to continue without waiting for the output of the shell_exec.

    Example:

    shell_exec('php /var/www/html/my_php_app.php > /dev/null 2>/dev/null &');
    

    The /dev/null 2>/dev/null part tells bash to send the output to null/nothing. (No Output)

    The & tells bash to run the script/command in the background. (You can even do this in a regular ssh/bash terminal!)

    Note that it is possible that your background script can now be running more than once at a time.

    If you do not want this, (only one instance at any one time) you can use pid/lock files. Here is an example of something you could use at the top of your php script that shell_exec calls.

    $lock_file = fopen('/var/www/html/my_php_app.pid', 'c');
    $got_lock = flock($lock_file, LOCK_EX | LOCK_NB, $wouldblock);
    if ($lock_file === false || (!$got_lock && !$wouldblock)) {
        throw new Exception(
            "Unexpected error opening or locking lock file. Perhaps you " .
            "don't  have permission to write to the lock file or its " .
            "containing directory?"
        );
    }
    else if (!$got_lock && $wouldblock) {
        exit("Another instance is already running; terminating.\n");
    }
    //Continue with the script.