PHP - how to best determine if the current invocation is from CLI or web server?

Viewed 99359

I need to determine whether the current invocation of PHP is from the command line (CLI) or from the web server (in my case, Apache with mod_php).

Any recommended methods?

19 Answers

php_sapi_name is the function you will want to use as it returns a lowercase string of the interface type. In addition, there is the PHP constant PHP_SAPI.

Documentation can be found here: http://php.net/php_sapi_name

For example, to determine if PHP is being run from the CLI, you could use this function:

function isCommandLineInterface()
{
    return (php_sapi_name() === 'cli');
}

I think he means if PHP CLI is being invoked or if it is a response from a web request. The best way would be to use php_sapi_name() which if it was running a web request would echo Apache if that is what it was running.

To list of a few taken from the php docs on php_sapi_name():

  • aolserver
  • apache
  • apache2filter
  • apache2handler
  • caudium
  • cgi (until PHP 5.3)
  • cgi-fcgi
  • cli
  • cli-server (Built-in web server as of PHP 5.4)
  • continuity
  • embed
  • fpm-fcgi
  • isapi
  • litespeed
  • milter
  • nsapi
  • phttpd
  • pi3web
  • roxen
  • thttpd
  • tux
  • webjames

Try

isset($_SERVER['REQUEST_METHOD'])

if it's set, you're in a browser.

Alternatlely, you could check if

isset($_SERVER['argv'])

but that might not be true on windows CLI, IDK.

I would suggest to check if some of the entries of the $_SERVER array are set.

E.g.:

if (isset($_SERVER['REQUEST_METHOD'])) {
        print "HTTP request\n";
} else {
        print "CLI invocation\n";
}

The correct answer to this question depends on the real intent behind it:

  • Is the SAPI the deciding factor (web-context or not)?
  • Or is the information interpreted as 'running in a tty'?

If the former the answers given and comments written are enough to find a solution that works.

If the latter, the recipes given here will fail if the tool is run as cronjob, or as background-job from another daemon -- in that case I suggest to further test if STDIN is a TTY:

function at_tty() {
    return defined("\STDIN") && posix_isatty(\STDIN);
}

How, so many complicated solutions. How about ...

if($_SERVER['REQUEST_SCHEME']=="http" or $_SERVER['REQUEST_SCHEME']=="https"){
    // must be browser :)
}

A practical hint

The official way (as told by many) is PHP_SAPI as a constant, or php_sapi_name() as a function, they both return cli when you're in a command line situation. They're right.

But!...

Consider using $_SERVER["argv"] (also $argv in most cases) which is null when you run in a browser, and an array when you've been called from command line. The advantage of this approach (or using both) is that you can simulate a terminal run in a browser, by just giving a (fake) value to the $argv / $_SERVER["argv"] variable. This comes in handy when you test on an outside server (prod, staging, etc) where you typically won't get SSH access.

The best way to do this is keeping in mind whether you may or may not need a CLI simulation, and use both $argv and PHP_SAPI to coordinate this - e.g. you may need to output an extra <pre> tag beforehand if PHP_SAPI is not "cli" but $argv has a value.

My preferred method:

if (array_key_exists('SHELL', $_ENV)) {
  echo "Console invocation";
}
else {
  echo "HTTP invocation";
}

I'd try:

echo exec('whoami');

Usually webservers are run under a different username, so that should be telling.

Related