Eu preciso determinar se a chamada atual do PHP é da linha de comando (CLI) ou do servidor da Web (no meu caso, Apache com mod_php).
Algum método recomendado?
Eu preciso determinar se a chamada atual do PHP é da linha de comando (CLI) ou do servidor da Web (no meu caso, Apache com mod_php).
Algum método recomendado?
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 PHP PHP_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:
function isCommandLineInterface()
{
return (php_sapi_name() === 'cli');
}
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ível apache2handler
. Espero que isto ajude. Eu precisava usar php-cgi
para introduzir $_GET
variáveis: php-cgi myscript.php arg1=one arg2=two
. Testar para não igual a apache2handler
deve estar ok para apache
.
"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
function is_cli()
{
if ( defined('STDIN') )
{
return true;
}
if ( php_sapi_name() === 'cli' )
{
return true;
}
if ( array_key_exists('SHELL', $_ENV) ) {
return true;
}
if ( empty($_SERVER['REMOTE_ADDR']) and !isset($_SERVER['HTTP_USER_AGENT']) and count($_SERVER['argv']) > 0)
{
return true;
}
if ( !array_key_exists('REQUEST_METHOD', $_SERVER) )
{
return true;
}
return false;
}
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 chave REQUEST_METHOD
, ela só existe quando a solicitação é feita via Web; portanto, o autor está absolutamente no alvo ao procurá-la.
return false;
ou deveria if ( ! 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', 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.
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.
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 documentosphp_sapi_name()
php em :
function is_cli() {
return !http_response_code();
}
exemplo:
if (is_cli()) {
echo 'command line';
} else {
echo 'browser';
}
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 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)
Eu usei isso:
php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)
Isto é da base de código Drush, environment.inc, onde eles têm verificação semelhante a fazer.
Experimentar
isset($_SERVER['REQUEST_METHOD'])
se estiver definido, você está em um navegador.
Como alternativa, você pode verificar se
isset($_SERVER['argv'])
mas isso pode não ser verdade no Windows CLI, IDK.
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
Eu sugeriria verificar se algumas das entradas da matriz $ _SERVER estão definidas.
Por exemplo:
if (isset($_SERVER['REQUEST_METHOD'])) {
print "HTTP request\n";
} else {
print "CLI invocation\n";
}
php-cgi
linha de comando, ele irá configurá-lo para GET
para:php-cgi -f file.php arg1=2
Meu método preferido:
if (array_key_exists('SHELL', $_ENV)) {
echo "Console invocation";
}
else {
echo "HTTP invocation";
}
// Detect CLI calls
define("IS_CLI_CALL",( strcmp(php_sapi_name(),'cli') == 0 ));
if(IS_CLI_CALL){
//do you stuff here
}
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:
if (isset($argv)) {
// Do the cli thing.
}
Com base na resposta de Silver Moon acima , estou usando esta função para retornar quebras de linha corretas:
/**
* Linebreak function
* @return "/n" if cli, else return <br>
*/
protected static function lb(){
return (defined('STDIN') || php_sapi_name() === 'cli' || isset($_ENV['SHELL']) ||
(empty($_SERVER['REMOTE_ADDR']) && !isset($_SERVER['HTTP_USER_AGENT']) && count($_SERVER['argv']) > 0) ||
!isset($_SERVER['REQUEST_METHOD'])) ? "\n" : "<br>";
}
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:
function at_tty() {
return defined("\STDIN") && posix_isatty(\STDIN);
}
Eu tentaria:
echo exec('whoami');
Normalmente, os servidores da web são executados com um nome de usuário diferente, o que deve ser revelador.