Qual è il modo canonico per determinare la linea di comando rispetto all'esecuzione http di uno script PHP?


155

Ho uno script PHP che deve determinare se è stato eseguito tramite la riga di comando o tramite HTTP, principalmente per scopi di formattazione dell'output. Qual è il modo canonico di farlo? Avevo pensato che fosse da ispezionare SERVER['argc'], ma risulta che questo è popolato, anche quando si utilizza l'API del server "Apache 2.0 Handler".

Risposte:


228

Usa la php_sapi_name()funzione

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

Ecco alcune note rilevanti dai documenti:

php_sapi_name - Restituisce il tipo di interfaccia tra web server e PHP

Sebbene non esaustivi, i possibili valori di ritorno includono aolserver, apache, apache2filter, apache2handler, caudium, cgi (fino a PHP 5.3), cgi-fcgi, cli, cli-server, continuità, embed, isapi, litespeed, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux e webjames.

In PHP> = 4.2.0, esiste anche una costante predefinita PHP_SAPI, che ha lo stesso valore di php_sapi_name().


Grazie. Sono incuriosito dal perché il doc. L'esempio controlla i primi 3 caratteri, mentre la descrizione afferma che la stringa dovrebbe essere esattamente "cgi" ma, a parte questo, penso che sia perfetto.
Bobby Jack,

a meno che, naturalmente, la stringa restituita fosse 'cgi', che è anche indicativa dell'esecuzione di php dalla console. Come in whaddayaknow, il mio caso.
Adriano Varoli Piazza

@Adriano: forse nel tuo caso php-cgi è usato per eseguire lo script.

3
@Bobby, l'esempio nella documentazione di php.net in realtà corrisponde sia a "cgi" che a "cgi-fcgi" guardando solo i primi tre caratteri della stringa ... ecco perché ed effettivamente ha senso. Semmai è solo per tornare @hop per aver chiamato php nessuna lingua per programmatori seri: D
ChrisR

1
una nota interessante qui: php.net/manual/it/function.php-sapi-name.php è che a seconda del binario effettivamente chiamato, puoi eseguire php dalla riga di comando e ottenere comunque cgi-fgi
DAB

22

Questo funzionerà sempre. (Se la versione di PHP è 4.2.0 o successiva)

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

Il che lo rende facile da usare nella parte superiore dei tuoi script:

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

8
Il tuo secondo frammento sembra un non sequitur, mi aspettoCLI or die('not allowed');
Madbreaks

1
@Madbreaks, stavo affermando due usi separati. Stavo assumendo l' uno o l'altro - ma se li usi entrambi CLI or die('not allowed');è perfetto.
Xeoncross,

Grazie per il chiarimento, +1
Madbreaks

7
Which makes it easy to use at the top of your scriptsnon lo fa sembrare come due usi separati. Sì, sono un negromante.
George Dimitriadis,

9

Ecco l'implementazione di 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)));
}

Tuttavia Drupal 8 consiglia di utilizzarePHP_SAPI === 'cli'


8

penso

$_SERVER['REMOTE_ADDR']

non verrà popolato dalla CLI.

Inoltre, tutte le chiavi HTTP_ * nel superglobal $ _SERVER non verranno popolate dalla CLI, o lo faranno nel modo giusto hop appena menzionato :-)


4

La pagina della documentazione per php_sapi_name indica chiaramente come funziona:

Restituisce una stringa minuscola che descrive il tipo di interfaccia (API del server, SAPI) che PHP sta utilizzando ....

Sebbene non esaustivi, i possibili valori di ritorno includono aolserver, apache, apache2filter, apache2handler, caudium, cgi (fino a PHP 5.3), cgi-fcgi, cli, continuità, embed, isapi, litespeed, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux e webjames.

Non sono sicuro del motivo per cui hop non pensi che PHP sia per programmatori seri (sono un programmatore serio e utilizzo PHP quotidianamente), ma se vuole aiutare a chiarire la documentazione, forse può controllare tutti i possibili server Web su cui PHP può essere eseguito e determinare i nomi di tutti i possibili tipi di interfaccia per ciascun server. Assicurati di mantenere aggiornato l'elenco quando vengono aggiunti nuovi server Web e interfacce.

Inoltre, Bobby ha detto:

Sono incuriosito dal perché il doc. esempio controlla i primi 3 caratteri, mentre la descrizione indica che la stringa deve essere esattamente "CGI"

La descrizione per l'esempio afferma:

Questo esempio verifica la sottostringa cgi perché potrebbe anche essere cgi-fcgi.


Ah - o ero incredibilmente inosservato quel giorno, o l'esempio è stato aggiornato da quando ho fatto quel commento. Tuttavia, sono pienamente d'accordo con i tuoi punti su PHP; il bashing diventa MOLTO stancante.
Bobby Jack,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.