Eu fiz uma pesquisa: se você invocar o script com php-cgiisso não funcionará. Por sua vez, ele retornará cgi-fcgiString. Se você carregar o script como uma página da web a partir de um navegador, será possível apache2handler. Espero que isto ajude. Eu precisava usar php-cgipara introduzir $_GETvariáveis: php-cgi myscript.php arg1=one arg2=two. Testar para não igual a apache2handlerdeve estar ok para apache.
Sebastian
3
Uma pequena ressalva sobre esse método: ele não retornará "cli"quando executado a partir de um trabalho cron. Há um número de diferentes chaves para você escolher de dentro $_SERVERpara determinar com mais segurança se a solicitação veio via HTTP ou não.
omninonsense
2
@omninonsense Eu testei com o PHP 7.2.7 e ele retorna cli.
Jose Nobile
38
Uso essa função há alguns anos
function is_cli(){if(defined('STDIN')){returntrue;}if( php_sapi_name()==='cli'){returntrue;}if( array_key_exists('SHELL', $_ENV)){returntrue;}if( empty($_SERVER['REMOTE_ADDR'])and!isset($_SERVER['HTTP_USER_AGENT'])and count($_SERVER['argv'])>0){returntrue;}if(!array_key_exists('REQUEST_METHOD', $_SERVER)){returntrue;}returnfalse;}
@biziclop, a verificação array_key_exists('REQUEST_METHOD', $_SERVER)está correta para ajudar na detecção da fonte da solicitação . Quando na CLI , a $_SERVERmatriz Super Global NÃO TERÁ a chave REQUEST_METHOD, ela só existe quando a solicitação é feita via Web; portanto, o autor está absolutamente no alvo ao procurá-la.
Julio Marchi
1
@ JulioMarchi: mas não deveria return false;ou deveria if ( ! array_key_exists(…)) return true;?
biziclop
2
@ Biziclop, você está totalmente certo !!!! Como eu poderia desperdiçar estas enorme pequeno detalhe ??? Que vergonha... :). Certamente, se a CHAVE NÃO'REQUEST_METHOD' for encontrada, a função deverá retornar para indicar "CLI". Peço desculpas por não prestar atenção ao escopo da própria função ... O autor deve corrigi-lo porque a função realmente funciona! FALSE
Julio Marchi
Essa função funcionou no meu caso, não php_sapi_name (), pois eu precisava distinguir entre solicitações da web e execuções de cronjob, e o resultado php_sapi_name () foi "php-cgi" nos dois casos.
Luis.ap.uyen
36
php_sapi_name()realmente não é a melhor maneira de executar essa verificação, pois depende da verificação de muitos valores possíveis. O binário php-cgi pode ser chamado a partir da linha de comando, de um script shell ou como um trabalho cron e (na maioria dos casos) eles também devem ser tratados como 'cli', mas php_sapi_name()retornarão valores diferentes para eles (observe que isso não é '' o caso da versão simples do PHP, mas você deseja que seu código funcione em qualquer lugar, certo?). Sem mencionar que no próximo ano poderá haver novas maneiras de usar PHP que não podemos saber agora. Prefiro não pensar nisso, quando tudo que me interessa é o clima, devo incluir minha saída em HTML ou não.
Felizmente, o PHP tem uma maneira de verificar isso especificamente. Basta usar http_response_code()sem nenhum parâmetro e ele retornará TRUE se executado em um ambiente do tipo servidor da web e FALSE se executado em um ambiente do tipo CLI. Aqui está o código:
$is_web=http_response_code()!==FALSE;
Isso funcionará mesmo se você acidentalmente (?) Definir um código de resposta de um script em execução na CLI (ou algo como a CLI) antes de chamá-lo.
Esta questão já era antiga quando a respondi. A votação antecipada desta resposta provavelmente teria sido mais útil do que postar outra resposta duplicada, exceto sem a explicação.
krowe2
Com relação a "Isso funcionará mesmo se você acidentalmente (?) Definir um código de resposta de um script executado na CLI [...] (...) antes de chamá-lo.": (Pelo menos) a partir do PHP 7.4.3, isso é Não é verdade. http_response_code()define código / retorna código definido ao executar a partir da CLI. Verificado por <?php function t() { echo var_export(http_response_code(), true) . ' -> ' . (http_response_code() !== false ? 'web' : 'cli') . "\n"; } t(); http_response_code(200); t(); http_response_code(false); t();. Portanto, se http_response_code()===falseé uma aposta segura assumir o CLI, mas se não, você precisa verificar também outras métricas.
Sebastian B.
23
Eu acho que ele quer dizer se o PHP CLI está sendo chamado ou se é uma resposta de uma solicitação da web. A melhor maneira seria usar o php_sapi_name()que, se estivesse executando uma solicitação da Web, ecoaria o Apache se era isso que estava executando.
No manual, "FALSE será retornado se o response_code não for fornecido e não for invocado em um ambiente de servidor da web (como em um aplicativo CLI). TRUE será retornado se o response_code for fornecido e não for invocado em um servidor da web ambiente (mas apenas quando nenhum status de resposta anterior foi definido) ". Você conseguiu sua lógica de trás para frente.
krowe2
1
+1. Surpreendente. Depois de tantos anos de pesquisa infrutífera ... por meio deste, concedo a você o Prêmio Nobel Memorial em PHPics, compartilhado com @ krowe2 por sua inestimável contribuição de realmente fazê-lo funcionar. Parabéns!
Sz.
É possível que algo tenha definido o código de resposta ... http_response_code(200);... se eu ligar agora, http_response_code()ele retornará 200;
Brad Kent
@BradKent APENAS se você chamar isso de um ambiente web e, nesse caso, essa verificação ainda funcionará desde que você não tenha definido o código de status como zero (que é um código de status HTTP inválido). Minha versão funcionará mesmo nesse caso, porque verifica especificamente contra FALSE. Se http_response_code();for chamado de um ambiente CLI, ele sempre retornará FALSE, independentemente do código de status real. Eu já expliquei isso na minha resposta, mas você também pode descobrir isso lendo a página do manual em "Return Values" ou tentando.
precisa saber é o seguinte
@ krowe2 php -r 'http_response_code(200); echo http_response_code()."\n";' produz "200" A menos que você possa garantir que alguma biblioteca ou estrutura ignorante não tenha definido o código de resposta http_response_code(mesmo em um ambiente CLI), isso funcionará. Pessoalmente, eu uso$isCli = \defined('STDIN') || isset($_SERVER['argv']) || \array_key_exists('REQUEST_METHOD', $_SERVER)
Embora não seja a "correta" responder que poderia ser o mais confiável
challet
2
De acordo com http://jp2.php.net/manual/en/features.commandline.php Há um número de constantes definidas apenas ao executar a partir da CLI. Essas constantes são STDIN, STDOUT e STDERR. Testar para um desses dirá se ele está no modo CLI
Uma maneira fácil é interrogar a $argvvariável (o que você provavelmente fará para os parâmetros da linha de comando). Mesmo se não houver parâmetros, $argvretorna uma matriz vazia.
Se estiver definido, o cli foi usado. Você pode então assumir que todas as outras invocações são feitas através de um servidor web ou outro.
A resposta correta para esta pergunta depende da intenção real por trás dela:
O SAPI é o fator decisivo (contexto da Web ou não)?
Ou a informação é interpretada como 'executando em um tty'?
Se o primeiro, as respostas e os comentários escritos são suficientes para encontrar uma solução que funcione.
Neste último caso, as receitas fornecidas aqui falharão se a ferramenta for executada como cronjob ou como trabalho em segundo plano de outro daemon - nesse caso, sugiro testar mais se STDINé um TTY:
function at_tty(){returndefined("\STDIN")&& posix_isatty(\STDIN);}
Respostas:
php_sapi_name
é a função que você deseja usar, pois retorna uma sequência minúscula do tipo de interface. Além disso, há a constante PHPPHP_SAPI
.A documentação pode ser encontrada aqui: http://php.net/php_sapi_name
Por exemplo, para determinar se o PHP está sendo executado na CLI, você pode usar esta função:
fonte
return php_sapi_name() == 'cli';
php-cgi
isso não funcionará. Por sua vez, ele retornarácgi-fcgi
String. Se você carregar o script como uma página da web a partir de um navegador, será possívelapache2handler
. Espero que isto ajude. Eu precisava usarphp-cgi
para introduzir$_GET
variáveis:php-cgi myscript.php arg1=one arg2=two
. Testar para não igual aapache2handler
deve estar ok paraapache
."cli"
quando executado a partir de um trabalho cron. Há um número de diferentes chaves para você escolher de dentro$_SERVER
para determinar com mais segurança se a solicitação veio via HTTP ou não.Uso essa função há alguns anos
fonte
array_key_exists('REQUEST_METHOD', $_SERVER) return true;
WAT?array_key_exists('REQUEST_METHOD', $_SERVER)
está correta para ajudar na detecção da fonte da solicitação . Quando na CLI , a$_SERVER
matriz Super Global NÃO TERÁ a chaveREQUEST_METHOD
, ela só existe quando a solicitação é feita via Web; portanto, o autor está absolutamente no alvo ao procurá-la.return false;
ou deveriaif ( ! array_key_exists(…)) return true;
?'REQUEST_METHOD'
for encontrada, a função deverá retornar para indicar "CLI". Peço desculpas por não prestar atenção ao escopo da própria função ... O autor deve corrigi-lo porque a função realmente funciona!FALSE
php_sapi_name()
realmente não é a melhor maneira de executar essa verificação, pois depende da verificação de muitos valores possíveis. O binário php-cgi pode ser chamado a partir da linha de comando, de um script shell ou como um trabalho cron e (na maioria dos casos) eles também devem ser tratados como 'cli', masphp_sapi_name()
retornarão valores diferentes para eles (observe que isso não é '' o caso da versão simples do PHP, mas você deseja que seu código funcione em qualquer lugar, certo?). Sem mencionar que no próximo ano poderá haver novas maneiras de usar PHP que não podemos saber agora. Prefiro não pensar nisso, quando tudo que me interessa é o clima, devo incluir minha saída em HTML ou não.Felizmente, o PHP tem uma maneira de verificar isso especificamente. Basta usar
http_response_code()
sem nenhum parâmetro e ele retornará TRUE se executado em um ambiente do tipo servidor da web e FALSE se executado em um ambiente do tipo CLI. Aqui está o código:Isso funcionará mesmo se você acidentalmente (?) Definir um código de resposta de um script em execução na CLI (ou algo como a CLI) antes de chamá-lo.
fonte
http_response_code()
define código / retorna código definido ao executar a partir da CLI. Verificado por<?php function t() { echo var_export(http_response_code(), true) . ' -> ' . (http_response_code() !== false ? 'web' : 'cli') . "\n"; } t(); http_response_code(200); t(); http_response_code(false); t();
. Portanto, sehttp_response_code()===false
é uma aposta segura assumir o CLI, mas se não, você precisa verificar também outras métricas.Eu acho que ele quer dizer se o PHP CLI está sendo chamado ou se é uma resposta de uma solicitação da web. A melhor maneira seria usar o
php_sapi_name()
que, se estivesse executando uma solicitação da Web, ecoaria o Apache se era isso que estava executando.Para listar algumas extraídas dos documentos
php_sapi_name()
php em :fonte
Isso deve lidar com todos os casos (incluindo php-cgi)
fonte
exemplo:
fonte
http_response_code(200);
... se eu ligar agora,http_response_code()
ele retornará 200;http_response_code();
for chamado de um ambiente CLI, ele sempre retornará FALSE, independentemente do código de status real. Eu já expliquei isso na minha resposta, mas você também pode descobrir isso lendo a página do manual em "Return Values" ou tentando.php -r 'http_response_code(200); echo http_response_code()."\n";'
produz "200" A menos que você possa garantir que alguma biblioteca ou estrutura ignorante não tenha definido o código de respostahttp_response_code
(mesmo em um ambiente CLI), isso funcionará. Pessoalmente, eu uso$isCli = \defined('STDIN') || isset($_SERVER['argv']) || \array_key_exists('REQUEST_METHOD', $_SERVER)
Eu usei isso:
Isto é da base de código Drush, environment.inc, onde eles têm verificação semelhante a fazer.
fonte
register_argc_argv
estiver definido, a passagem de qualquer quantidade de valores GET fará comargc
que não seja 0. #Experimentar
se estiver definido, você está em um navegador.
Como alternativa, você pode verificar se
mas isso pode não ser verdade no Windows CLI, IDK.
fonte
De acordo com http://jp2.php.net/manual/en/features.commandline.php Há um número de constantes definidas apenas ao executar a partir da CLI. Essas constantes são STDIN, STDOUT e STDERR. Testar para um desses dirá se ele está no modo CLI
fonte
Joomla Way
fonte
Eu sugeriria verificar se algumas das entradas da matriz $ _SERVER estão definidas.
Por exemplo:
fonte
php-cgi
linha de comando, ele irá configurá-lo paraGET
para:php-cgi -f file.php arg1=2
Meu método preferido:
fonte
fonte
Uma maneira fácil é interrogar a
$argv
variável (o que você provavelmente fará para os parâmetros da linha de comando). Mesmo se não houver parâmetros,$argv
retorna uma matriz vazia.Se estiver definido, o cli foi usado. Você pode então assumir que todas as outras invocações são feitas através de um servidor web ou outro.
por exemplo:
fonte
Com base na resposta de Silver Moon acima , estou usando esta função para retornar quebras de linha corretas:
fonte
A resposta correta para esta pergunta depende da intenção real por trás dela:
Se o primeiro, as respostas e os comentários escritos são suficientes para encontrar uma solução que funcione.
Neste último caso, as receitas fornecidas aqui falharão se a ferramenta for executada como cronjob ou como trabalho em segundo plano de outro daemon - nesse caso, sugiro testar mais se
STDIN
é um TTY:fonte
Como, tantas soluções complicadas. E se ...
fonte
Eu tentaria:
Normalmente, os servidores da web são executados com um nome de usuário diferente, o que deve ser revelador.
fonte