Qual é a maneira canônica de determinar a linha de comando versus a execução http de um script PHP?


155

Eu tenho um script PHP que precisa determinar se foi executado via linha de comando ou via HTTP, principalmente para fins de formatação de saída. Qual é a maneira canônica de fazer isso? Eu pensei que era para inspecionar SERVER['argc'], mas acontece que isso é preenchido, mesmo ao usar a API do servidor 'Apache 2.0 Handler'.

Respostas:


228

Use a php_sapi_name()função

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

Aqui estão algumas notas relevantes dos documentos:

php_sapi_name - Retorna o tipo de interface entre servidor web e PHP

Embora não sejam exaustivos, os possíveis valores de retorno incluem aolserver, apache, apache2filter, apache2handler, caudium, cgi (até PHP 5.3), cgi-fcgi, cli, cli-server, continuidade, embed, isapi, litespeed, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux e webjames.

No PHP> = 4.2.0, também há uma constante predefinida PHP_SAPI, que tem o mesmo valor que php_sapi_name().


Obrigado. Estou intrigado com o motivo do documento. O exemplo inspeciona os três primeiros caracteres, enquanto a descrição indica que a string deve ser exatamente "cgi", mas, além disso, acho que isso é perfeito.
Bobby Jack

a menos que, é claro, a string retornada seja 'cgi', o que também indica o php sendo executado no console. Como, whaddayaknow, meu caso.
Adriano Varoli Piazza

@ Adriano: talvez no seu caso o php-cgi seja usado para executar o script.

3
@Bobby, o exemplo nos documentos do php.net realmente combina "cgi" e "cgi-fcgi", apenas olhando os três primeiros caracteres da string ... é por isso que faz sentido. Se alguma coisa é apenas para voltar @hop para chamar php nenhuma linguagem para programadores sérios: D
ChrisR

1
uma observação interessante aqui: php.net/manual/en/function.php-sapi-name.php é que, dependendo do binário real chamado, você pode executar o php na linha de comando e ainda obter o cgi-fgi
DAB

22

Isso sempre funcionará. (Se a versão do PHP for 4.2.0 ou superior)

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

O que facilita o uso na parte superior de seus scripts:

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

8
Seu segundo trecho parece ser um non sequitur, eu esperariaCLI or die('not allowed');
Madbreaks

1
@ Madbreaks, eu estava afirmando dois usos separados. Eu estava assumindo qualquer um ou o outro - mas se você usar ambos, então CLI or die('not allowed');é perfeito.
Xeoncross

Obrigado por esclarecer, +1
Madbreaks

7
Which makes it easy to use at the top of your scriptsrealmente não soa como dois usos separados. Sim, sou um necromante.
George Dimitriadis

9

Aqui está a implementação do 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)));
}

No entanto, o Drupal 8 recomenda o uso dePHP_SAPI === 'cli'


8

eu acho que

$_SERVER['REMOTE_ADDR']

não será preenchido a partir da CLI.

Além disso, todas as chaves HTTP_ * na superglobal $ _SERVER não serão preenchidas a partir da CLI, ou farão da maneira correta o salto que acabamos de mencionar :-)


4

A página de documentação para php_sapi_name indica claramente como funciona:

Retorna uma string em minúscula que descreve o tipo de interface (a API do servidor, SAPI) que o PHP está usando ....

Embora não seja exaustivo, os possíveis valores de retorno incluem aolserver, apache, apache2filter, apache2handler, caudium, cgi (até PHP 5.3), cgi-fcgi, cli, continuidade, incorporação, isapi, litespeed, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux e webjames.

Não sei por que o hop não pensa que o PHP é para programadores sérios (sou um programador sério e uso o PHP diariamente), mas se ele quiser ajudar a esclarecer a documentação, talvez possa auditar todos os servidores da Web possíveis que o PHP possa executar e determinar os nomes de todos os tipos de interface possíveis para cada servidor. Apenas certifique-se de manter essa lista atualizada à medida que novos servidores e interfaces da Web forem adicionados.

Além disso, Bobby disse:

Estou intrigado com o motivo do documento. O exemplo inspeciona os três primeiros caracteres, enquanto a descrição indica que a sequência deve ser exatamente "CGI"

A descrição para o exemplo afirma:

Este exemplo verifica o substring cgi porque também pode ser cgi-fcgi.


Ah - ou eu estava sendo incrivelmente desatento naquele dia, ou o exemplo foi atualizado desde que fiz esse comentário. No entanto, concordo plenamente com seus pontos de vista sobre PHP; o golpe fica MUITO cansativo.
Bobby Jack
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.