Was ist die kanonische Methode, um die Befehlszeile im Vergleich zur http-Ausführung eines PHP-Skripts zu bestimmen?

155

Ich habe ein PHP-Skript, das feststellen muss, ob es über die Befehlszeile oder über HTTP ausgeführt wurde, hauptsächlich für Ausgabeformatierungszwecke. Was ist der kanonische Weg, dies zu tun? Ich hatte gedacht, es wäre zu inspizieren SERVER['argc'], aber es stellt sich heraus, dass dies ausgefüllt ist, selbst wenn die Server-API 'Apache 2.0 Handler' verwendet wird.

Bobby Jack
quelle

Antworten:

228

Verwenden Sie die php_sapi_name()Funktion.

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

Hier sind einige relevante Hinweise aus den Dokumenten:

php_sapi_name - Gibt den Schnittstellentyp zwischen Webserver und PHP zurück

Obwohl nicht erschöpfend, umfassen die möglichen Rückgabewerte aolserver, apache, apache2filter, apache2handler, caudium, cgi (bis PHP 5.3), cgi-fcgi, cli, cli-server, Kontinuität, Einbettung, isapi, litespeed, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux und webjames.

In PHP> = 4.2.0 gibt es auch eine vordefinierte Konstante PHP_SAPI, die den gleichen Wert wie hat php_sapi_name().

Andy Fleming
quelle
Vielen Dank. Ich bin gespannt, warum der Doc. Beispiel prüft die ersten 3 Zeichen, während die Beschreibung besagt, dass die Zeichenfolge genau "cgi" sein sollte, aber ansonsten denke ich, dass dies perfekt ist.
Bobby Jack
es sei denn natürlich, die zurückgegebene Zeichenfolge war 'cgi', was auch darauf hinweist, dass PHP von der Konsole ausgeführt wird. Wie in, whaddayaknow, mein Fall.
Adriano Varoli Piazza
@Adriano: Vielleicht wird in Ihrem Fall php-cgi verwendet, um das Skript auszuführen.
3
@Bobby, das Beispiel in den php.net-Dokumenten stimmt tatsächlich sowohl mit "cgi" als auch mit "cgi-fcgi" überein, indem nur die ersten drei Zeichen der Zeichenfolge betrachtet werden. Deshalb ist es tatsächlich sinnvoll. Wenn überhaupt, ist es nur, um @hop für den Aufruf von PHP keine Sprache für ernsthafte Programmierer zurück zu bekommen: D
ChrisR
1
Ein interessanter Hinweis hier: php.net/manual/en/function.php-sapi-name.php ist, dass Sie abhängig von der tatsächlich aufgerufenen Binärdatei php über die Befehlszeile ausführen und trotzdem cgi-fgi
DAB
22

Das wird immer funktionieren. (Wenn die PHP-Version 4.2.0 oder höher ist)

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

Das macht es einfach, oben in Ihren Skripten zu verwenden:

<?php PHP_SAPI === 'cli' or die('not allowed');
Xeoncross
quelle
8
Ihr zweites Snippet scheint kein Sequitur zu sein, würde ich erwartenCLI or die('not allowed');
Madbreaks
1
@ Madbreaks, ich habe zwei getrennte Verwendungen angegeben. Ich habe entweder das eine oder das andere angenommen - aber wenn Sie beide verwenden, CLI or die('not allowed');ist es perfekt.
Xeoncross
Vielen Dank für die Klarstellung, +1
Madbreaks
7
Which makes it easy to use at the top of your scriptsklingt nicht wirklich nach zwei getrennten Verwendungen. Ja, ich bin ein Nekromant.
George Dimitriadis
9

Hier ist die Implementierung von 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)));
}

Drupal 8 empfiehlt jedoch die VerwendungPHP_SAPI === 'cli'

ya.teck
quelle
8

Meiner Ansicht nach

$_SERVER['REMOTE_ADDR']

wird nicht von der CLI ausgefüllt.

Außerdem werden nicht alle HTTP_ * -Schlüssel im Superglobal $ _SERVER aus der CLI ausgefüllt, oder machen Sie es richtig, wie gerade erwähnt :-)

Vinko Vrsalovic
quelle
4

Auf der Dokumentationsseite für php_sapi_name wird klar angegeben, wie es funktioniert:

Gibt eine Zeichenfolge in Kleinbuchstaben zurück, die den Schnittstellentyp (Server-API, SAPI) beschreibt, den PHP verwendet.

Obwohl nicht erschöpfend, umfassen die möglichen Rückgabewerte aolserver, apache, apache2filter, apache2handler, caudium, cgi (bis PHP 5.3), cgi-fcgi, cli, Kontinuität, Einbettung, isapi, litespeed, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux und webjames.

Ich bin mir nicht sicher, warum Hop nicht glaubt, dass PHP für ernsthafte Programmierer gedacht ist (ich bin ein ernsthafter Programmierer und verwende PHP täglich), aber wenn er bei der Klärung der Dokumentation helfen möchte, kann er möglicherweise alle möglichen Webserver prüfen dass PHP ausgeführt werden kann und die Namen aller möglichen Schnittstellentypen für jeden Server ermittelt. Stellen Sie einfach sicher, dass diese Liste auf dem neuesten Stand ist, wenn neue Webserver und Schnittstellen hinzugefügt werden.

Außerdem sagte Bobby:

Ich bin gespannt, warum der Doc. Beispiel prüft die ersten 3 Zeichen, während die Beschreibung besagt, dass die Zeichenfolge genau "CGI" sein sollte.

Die Beschreibung für das Beispiel lautet:

In diesem Beispiel wird nach dem Teilstring cgi gesucht, da es sich auch um cgi-fcgi handeln kann.

Steve
quelle
Ah - entweder war ich an diesem Tag unglaublich unbeobachtet oder das Beispiel wurde aktualisiert, seit ich diesen Kommentar abgegeben habe. Stimmen Sie jedoch voll und ganz Ihren Punkten zu PHP zu. Das Bashing wird sehr anstrengend.
Bobby Jack