Php from command line
PHP scripts are usually opened in a web browser. But they can be run from command line or terminal as well. The syntax to run a script from commandline is very much similar to python or perl.
php /path/to/script/index.php
Inside a script it might be necessary to test if it is being run from command line or not. For example when a script is being from cron it might produce a different kind of output than when it is run from a browser url. In such cases the script needs to identify its running mode.
There are several ways to check if a php script is running from cli or not. Lets check them one by one
1. Check for the STDIN constant. STDIN is a constant that is defined when php is running from command line.
if(defined('STDIN') ) echo("Running from CLI"); else echo("Not Running from CLI");
However the above method has certain limitations. The test works very well when the script is being run using the php cli binary. In cronjobs for example a the command is specified as follows
php /path/to/script/index.php
Now the php command itself points to a php binary which can be either the php-cli binary or php-cgi binary. If it points to a php-cgi binary, like it happens on some hosting servers then the STDIN check will always be false. So the STDIN check method is not fully reliable. Lets take a look at another method for checking cli.
2. Check the php_sapi_name. The php_sapi_name function is supposed to return "cli" if the script is running from commandline.
if(php_sapi_name()==="cli") echo("Running from CLI"); else echo("Not Running from CLI");
But this method too suffers the same problem as STDIN. It will work only if the cli mode has been triggered by the php cli binary. If php-cgi was used to initiate the script from the command line, it would always return "cgi-fcgi" for example.
3. Check the PHP_SAPI constant. The PHP_SAPI constant is the same as php_sapi_name function. So it has the same issues as mentioned above.
if (PHP_SAPI === 'cli') echo("Running from CLI"); else echo("Not Running from CLI");
For cgi this approach can be useful :
if(stristr(PHP_SAPI , 'cgi') and getenv('TERM')) echo("Running from CLI"); else echo("Not Running from CLI");
Working Solution
On servers that have fastcgi as the php handler for example, the php binary might point to php-cgi. So to test cli in an interface independant manner a different kind of check has to be done. Which is to check the contents of the $_SERVER variable for example.
function is_cli() { if( empty($_SERVER['REMOTE_ADDR']) and !isset($_SERVER['HTTP_USER_AGENT']) and count($_SERVER['argv']) > 0) { return true; } return false; }
The above method should properly detect cli in all cases. Can add an STDIN check too.
function is_cli() { if( defined('STDIN') ) { return true; } if( empty($_SERVER['REMOTE_ADDR']) and !isset($_SERVER['HTTP_USER_AGENT']) and count($_SERVER['argv']) > 0) { return true; } return false; }
Looks neat. Try it.
Not exactly related to the topics, but I am facing a problem related to this. When I run ps -aux in my Namecheap server, it shows PHP processes wither the filenames, but when I run the same px -aux command in y VPS (with LAMP, i do not get the filenames but simply /usr/sbin/apache2 -k start
Any idea how to make my LAMP server in my VPS to show PHP filenames when I execute ps -aux ?
define(‘CLI’, defined(‘STDIN’) || (
empty($_SERVER[‘REMOTE_ADDR’])
&& !isset($_SERVER[‘HTTP_USER_AGENT’])
&& count($_SERVER[‘argv’]) > 0
));
if (CLI) {
// If called from CLI…
} else {
// ..or from a browser/wget call.
}
/**
* Detects whether the current script is running in a command-line environment.
*/
function is_cli() {
return (!isset($_SERVER[‘SERVER_SOFTWARE’]) && (php_sapi_name() == ‘cli’ || (is_numeric($_SERVER[‘argc’]) && $_SERVER[‘argc’] > 0)));
}
Thanks for this very informative and useful article!