What is the canonical way to determine commandline vs. http execution of a PHP script?

Use the php_sapi_name() function.

if (php_sapi_name() == "cli") {
    // In cli-mode
} else {
    // Not in cli-mode
}

Here are some relevant notes from the docs:

php_sapi_name — Returns the type of interface between web server and PHP

Although not exhaustive, the possible return values include aolserver, apache, apache2filter, apache2handler, caudium, cgi (until PHP 5.3), cgi-fcgi, cli, cli-server, continuity, embed, isapi, litespeed, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux, and webjames.

In PHP >= 4.2.0, there is also a predefined constant, PHP_SAPI, that has the same value as php_sapi_name().


This will always work. (If the PHP version is 4.2.0 or higher)

define('CLI', PHP_SAPI === 'cli');

Which makes it easy to use at the top of your scripts:

<?php PHP_SAPI === 'cli' or die('not allowed');

Here is Drupal 7 implementation: drupal_is_cli():

function drupal_is_cli() {
  return (!isset($_SERVER['SERVER_SOFTWARE']) && (php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)));
}

However Drupal 8 recommends using PHP_SAPI === 'cli'