Каков канонический способ определить выполнение PHP-скрипта из командной строки по сравнению с HTTP?

У меня есть сценарий PHP, который должен определить, был ли он выполнен через командную строку или через HTTP, в первую очередь для целей форматирования вывода. Как это сделать канонически? Я думал, что это нужно для проверки SERVER['argc'], но оказалось, что это заполнено, даже при использовании API сервера «Обработчик Apache 2.0».


person Bobby Jack    schedule 06.10.2008    source источник


Ответы (5)


Используйте функцию php_sapi_name().

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

Вот несколько важных примечаний из документов:

php_sapi_name - возвращает тип интерфейса между веб-сервером и PHP.

Возможные возвращаемые значения, хотя и не исчерпывающие, включают aolserver, apache, apache2filter, apache2handler, caudium, cgi (до PHP 5.3), cgi-fcgi, cli, cli-server, непрерывность, встраивание, isapi, litespeed, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux и webjames.

В PHP> = 4.2.0 также есть предопределенная константа PHP_SAPI, которая имеет то же значение, что и php_sapi_name().

person Community    schedule 06.10.2008
comment
Спасибо. Я заинтригован, почему документ. Пример проверяет первые 3 символа, в то время как в описании указано, что строка должна быть точно cgi, но, кроме этого, я думаю, что это идеально. - person Bobby Jack; 06.10.2008
comment
если, конечно, возвращенная строка не была «cgi», что также указывает на то, что php выполняется с консоли. Как в моем случае. - person Adriano Varoli Piazza; 28.09.2009
comment
@Adriano: возможно, в вашем случае php-cgi используется для выполнения скрипта. - person ; 23.02.2010
comment
@Bobby, пример в документации php.net фактически соответствует как cgi, так и cgi-fcgi, просто глядя на первые три символа строки ... поэтому и это действительно имеет смысл. Во всяком случае, это просто вернуть @hop за то, что он назвал php не языком для серьезных программистов: D - person ChrisR; 30.09.2010
comment
интересное примечание: php.net/manual/en/function.php -sapi-name.php заключается в том, что в зависимости от фактического вызываемого двоичного файла вы можете запускать php из командной строки и по-прежнему получать cgi-fgi - person DAB; 24.06.2015
comment
Этот фрагмент кода не является внедорожником: когда PHP запускается как CGI, функция php_sapi_name возвращает то же значение в HTTP или командной строке (пример: 'cgi-fcgi'). Это лучшие решения. - person Skrol29; 26.04.2018
comment
(php_sapi_name () == cli || die (только из командной строки)); в верхней части вашего скрипта - person relipse; 12.11.2019

Это всегда будет работать. (Если версия PHP 4.2.0 или выше)

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

Это упрощает использование в верхней части ваших скриптов:

<?php PHP_SAPI === 'cli' or die('not allowed');
person Xeoncross    schedule 08.12.2010
comment
Ваш второй фрагмент кажется неполным, я бы ожидал CLI or die('not allowed'); - person Madbreaks; 09.01.2013
comment
@Madbreaks, я говорил о двух разных вариантах использования. Я предполагал либо одно, либо другое - но если вы используете оба, то CLI or die('not allowed'); идеально. - person Xeoncross; 09.01.2013
comment
Which makes it easy to use at the top of your scripts на самом деле не похоже на два разных использования. Да, я некромант. - person George Dimitriadis; 08.06.2017

я думаю

$_SERVER['REMOTE_ADDR']

не будет заполняться из интерфейса командной строки.

Кроме того, все ключи HTTP_ * в суперглобале $ _SERVER не будут заполнены из интерфейса командной строки или сделают это правильно, как только что упомянуто :-)

person Vinko Vrsalovic    schedule 06.10.2008

Вот реализация 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 рекомендует использовать PHP_SAPI === 'cli'

person ya.teck    schedule 29.09.2012

На странице документации для php_sapi_name четко указано, как это работает:

Возвращает строку в нижнем регистре, которая описывает тип интерфейса (API сервера, SAPI), который использует PHP ....

Возможные возвращаемые значения, хотя и не являются исчерпывающими, включают aolserver, apache, apache2filter, apache2handler, caudium, cgi (до PHP 5.3), cgi-fcgi, cli, непрерывность, встраивание, isapi, litespeed, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux и webjames.

Я не уверен, почему Хоп не думает, что PHP предназначен для серьезных программистов (я серьезный программист и ежедневно использую PHP), но если он хочет помочь прояснить документацию, то, возможно, он сможет проверить все возможные веб-серверы. что PHP может работать и определять имена всех возможных типов интерфейса для каждого сервера. Просто не забывайте обновлять этот список по мере добавления новых веб-серверов и интерфейсов.

Также Бобби сказал:

Я заинтригован, почему документ. пример проверяет первые 3 символа, в то время как в описании указано, что строка должна быть в точности CGI

Описание примера гласит:

В этом примере проверяется наличие подстроки cgi, поскольку она также может быть cgi-fcgi.

person Steve    schedule 05.08.2009
comment
Ах, либо я был невероятно ненаблюдающим в тот день, либо пример был обновлен с тех пор, как я сделал этот комментарий. Тем не менее, полностью согласен с вашим мнением о PHP; избиение становится ОЧЕНЬ утомительным. - person Bobby Jack; 10.08.2009