How to execute a shell command using PHP without await for the result (asynchronous) in Linux and windows environments

There are many cases where you'll prefer to execute a php script with the console instead of a UI, but there are some cases where to use an UI is the only way as is the client who triggers the action.

Probably you already know how to execute a bash task using PHP, but what if your task is too heavy and it takes too long to be accomplished ? No one wants to see a progressbar for hour expecting for an answer from the server ... at less not with things of the job.

In this case, you'll want to ignore the output and let your task running in the background. To achieve our goal we need to use the system function in windows and shell_exec function for ubuntu and linux.

shell_execute : Executes a command via shell and return the complete output as a string (but will prevent that in this case).

system : Execute an external program and display the output (and neither in this case).

Both functions allow you to do something with the command line, however we are going to prevent that these functions await for the output in every platform using a simple trick.

The following function will allow you to do the trick easily in most of the cases :

<?php
/**
* Executes a console command (like execute the command via putty) in
* a linux environment or windows from php without await for the result.
* 
* Useful for execute extense tasks.
* 
* @param {String} $comando
*/
function executeAsyncShellCommand($comando = null){
   if(!$comando){
       throw new Exception("No command given");
   }
   // If windows, else
   if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
       system($comando." > NUL");
   }else{
       shell_exec("/usr/bin/nohup ".$comando." >/dev/null 2>&1 &");
   }
}

The function expects the input of the shell as first parameter :

<?php
executeAsyncShellCommand(`echo hello`);

Important note : in some linux environments or Windows, you'll need to change the quotes ("" or '' for ``), otherwise the command will fail.

The important point is to know which command to use in which platform and redirect the output on it. For windows use {command} > NUL and for Linux,Ubuntu /usr/bin/nohup {command here} >/dev/null 2>&1 & will do the trick.

However, note that this function will help you with simple commands as php bin/console do:something , if your commands use a complex structure or it contains special characters you may want to implement it by yourself according to your needs.

The following self-written snippet writes a file in windows from php with system function and special characters being escaped thanks to the escapeshellcmd function :

Note : escapeshellcmd escapes any characters in a string that might be used to trick a shell command into executing arbitrary commands.

<?php

$filecontent = escapeshellcmd("> something that could'nt work in the command line < Hello world! I'm going to s@y sömething with weird characters");
$comando = `echo {$filecontent} > foo.txt`;

if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
    system($comando." > NUL");
}else{
    shell_exec("/usr/bin/nohup ".$comando." >/dev/null 2>&1 &");
} 

Tips to consider

  • Test your command live in the command line to see if it works alone, if it does, then it will work with the function.
  • This method comes in handy if you need to execute long tasks and the user may not want to wait or see the progress.
  • If you use the command to execute another in PHP , remember to give a higher limit time with ini_set('max_execution_time', seconds) of execution for both the function and the script that will be executed as the default time limit is of 30 seconds.
  • The system and shell_exec methods always expects for the output, there's no way to prevent it, however we use the trick to redirect a null output for every platform.

Have fun !

Become a more social person