Quelle est la manière canonique de déterminer l'exécution en ligne de commande par rapport à l'exécution http d'un script PHP?

155

J'ai un script PHP qui doit déterminer s'il a été exécuté via la ligne de commande ou via HTTP, principalement à des fins de formatage de sortie. Quelle est la manière canonique de faire cela? J'avais pensé que c'était à inspecter SERVER['argc'], mais il s'avère que cela est rempli, même lorsque vous utilisez l'API du serveur 'Apache 2.0 Handler'.

Bobby Jack
la source

Réponses:

228

Utilisez la php_sapi_name()fonction.

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

Voici quelques notes pertinentes tirées de la documentation:

php_sapi_name - Renvoie le type d'interface entre le serveur Web et PHP

Bien que non exhaustives, les valeurs de retour possibles incluent aolserver, apache, apache2filter, apache2handler, caudium, cgi (jusqu'à PHP 5.3), cgi-fcgi, cli, cli-server, continuité, embed, isapi, litespeed, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux et webjames.

En PHP> = 4.2.0, il existe également une constante prédéfinie,, PHP_SAPIqui a la même valeur que php_sapi_name().

Andy Fleming
la source
Merci. Je suis intrigué de savoir pourquoi le doc. exemple inspecte les 3 premiers caractères, tandis que la description indique que la chaîne doit être exactement "cgi" mais, à part ça, je pense que c'est parfait.
Bobby Jack
à moins, bien sûr, que la chaîne retournée ne soit «cgi», ce qui indique également que php est exécuté depuis la console. Comme dans, whaddayaknow, mon cas.
Adriano Varoli Piazza
@Adriano: peut-être que dans votre cas, php-cgi est utilisé pour exécuter le script.
3
@Bobby, l'exemple de la documentation php.net correspond en fait à "cgi" et "cgi-fcgi" en regardant simplement les trois premiers caractères de la chaîne ... c'est pourquoi et cela a du sens. Si quoi que ce soit, c'est juste pour revenir @hop pour appeler php pas de langage pour les programmeurs sérieux: D
ChrisR
1
une note intéressante ici: php.net/manual/en/function.php-sapi-name.php est que selon le binaire réel appelé, vous pouvez exécuter php à partir de la ligne de commande et toujours obtenir cgi-fgi
DAB
22

Cela fonctionnera toujours. (Si la version PHP est 4.2.0 ou supérieure)

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

Ce qui le rend facile à utiliser en haut de vos scripts:

<?php PHP_SAPI === 'cli' or die('not allowed');
Xeoncross
la source
8
Votre deuxième extrait semble être un non-sequitur, je m'attendraisCLI or die('not allowed');
Madbreaks
1
@Madbreaks, je mentionnais deux utilisations distinctes. Je supposais l' un ou l'autre - mais si vous utilisez les deux, CLI or die('not allowed');c'est parfait.
Xeoncross
Merci d'avoir clarifié, +1
Madbreaks
7
Which makes it easy to use at the top of your scriptsne fait pas vraiment penser à deux utilisations distinctes. Oui, je suis un nécromancien.
George Dimitriadis
9

Voici l'implémentation de Drupal 7: drupal_is_cli () :

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

Cependant Drupal 8 recommande d' utiliserPHP_SAPI === 'cli'

ya.teck
la source
8

je pense

$_SERVER['REMOTE_ADDR']

ne sera pas renseigné à partir de la CLI.

De plus, toutes les clés HTTP_ * de la superglobale $ _SERVER ne seront pas remplies à partir de la CLI, ou faites-le de la bonne manière, sautez juste mentionné :-)

Vinko Vrsalovic
la source
4

La page de documentation de php_sapi_name indique clairement son fonctionnement:

Renvoie une chaîne en minuscules qui décrit le type d'interface (l'API du serveur, SAPI) que PHP utilise ...

Bien que non exhaustives, les valeurs de retour possibles incluent aolserver, apache, apache2filter, apache2handler, caudium, cgi (jusqu'à PHP 5.3), cgi-fcgi, cli, continuité, embed, isapi, litespeed, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux et webjames.

Je ne sais pas pourquoi hop ne pense pas que PHP est destiné aux programmeurs sérieux (je suis un programmeur sérieux et j'utilise PHP quotidiennement), mais s'il veut aider à clarifier la documentation, alors peut-être qu'il peut auditer tous les serveurs Web possibles sur lequel PHP peut s'exécuter et déterminer les noms de tous les types d'interface possibles pour chaque serveur. Assurez-vous simplement de garder cette liste à jour au fur et à mesure que de nouveaux serveurs Web et interfaces sont ajoutés.

De plus, Bobby a déclaré:

Je suis intrigué de savoir pourquoi le doc. L'exemple inspecte les 3 premiers caractères, tandis que la description indique que la chaîne doit être exactement "CGI"

La description de l'exemple indique:

Cet exemple vérifie la sous-chaîne cgi car elle peut également être cgi-fcgi.

Steve
la source
Ah - soit j'étais incroyablement peu observateur ce jour-là, soit l'exemple a été mis à jour depuis que j'ai fait ce commentaire. Cependant, je suis entièrement d'accord avec vos points sur PHP; le dénigrement devient TRÈS fatiguant.
Bobby Jack