PHP-как лучше всего определить, является ли текущий вызов от CLI или веб-сервера?



Мне нужно определить, является ли текущий вызов PHP из командной строки (CLI) или с веб-сервера (в моем случае, Apache с mod_php).



все рекомендованные методы?

443   18  
PHP

18 ответов:

php_sapi_name - это функция, которую вы хотите использовать, поскольку она возвращает строчную строку типа интерфейса. Кроме того, есть php константа PHP_SAPI.

документация может быть найдена здесь:http://php.net/php_sapi_name

например, чтобы определить, выполняется ли PHP из CLI, вы можете использовать эту функцию:

function isCommandLineInterface()
{
    return (php_sapi_name() === 'cli');
}

Я думаю, что он имеет в виду, если PHP CLI вызывается или если это ответ от веб-запроса. Лучшим способом было бы использовать php_sapi_name() который, если он выполнял веб-запрос, будет эхом Apache, если это то, что он выполнял.

список из нескольких взятых из php документы на php_sapi_name():

  • aolserver
  • apache
  • apache2filter
  • apache2handler
  • caudium
  • cgi (до PHP 5.3)
  • cgi-fcgi
  • cli
  • cli-server (встроенный веб-сервер начиная с PHP 5.4)
  • непрерывность
  • embed
  • fpm-fcgi
  • isapi
  • litespeed
  • программа
  • nsapi
  • phttpd
  • pi3web
  • Роксен
  • thttpd
  • Тукс
  • webjames

Я использую эту функцию в течение нескольких лет

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;
}

php_sapi_name() - это действительно не лучший способ выполнить эту проверку, потому что это зависит от проверки против многих возможных значений. Двоичный файл php-cgi может быть вызван из командной строки, из сценария оболочки или как задание cron, и (в большинстве случаев) они также должны рассматриваться как "cli", но php_sapi_name() вернет различные значения для них (обратите внимание, что это не так с простой версией PHP, но вы хотите, чтобы ваш код работал где угодно, верно?). Не говоря уже о том, что в следующем году могут появиться новые способы используйте PHP, который мы не можем знать сейчас. Я бы предпочел не думать об этом, когда все, что меня волнует, - это погода, я должен обернуть свой вывод в HTML или нет.

к счастью, PHP имеет способ проверить это специально. Просто используйте http_response_code() без каких-либо параметров, и он вернет TRUE, если выполняется из среды типа веб-сервера и FALSE, если выполняется из среды типа CLI. Вот код:

$is_web=http_response_code()!==FALSE;

это даже будет работать, если вы случайно(?) установить код ответа из скрипта работает из командной строки (или что-то вроде командной строки) прежде чем вы это называете.

Это должно обрабатывать все случаи (включая php-cgi)

return (php_sapi_name() === 'cli' OR defined('STDIN'));
function is_cli() {
    return !http_response_code();
}

пример:

if (is_cli()) {
    echo 'command line';
} else {
    echo 'browser';
}

попробовать

isset($_SERVER['REQUEST_METHOD'])

если он установлен, вы в браузере.

альтернативно, вы можете проверить, если

isset($_SERVER['argv'])

но это может быть не так на Windows CLI, IDK.

я использовал этот:

php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)

Это из Drush codebase, environment.inc, где у них есть подобная проверка, чтобы сделать.

согласно http://jp2.php.net/manual/en/features.commandline.php Существует ряд констант, установленных только при запуске из CLI. Эти константы-STDIN, STDOUT и STDERR. Тестирование для одного из них скажет вам, если он находится в режиме cli

joomla way

if (array_key_exists('REQUEST_METHOD', $_SERVER)) die();

Я бы предложил проверить, если некоторые из записей переменная$_SERVER массив устанавливаются.

например:

if (isset($_SERVER['REQUEST_METHOD'])) {
        print "HTTP request\n";
} else {
        print "CLI invocation\n";
}

мой предпочтительный метод:

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

}

простой способ-допросить $argv переменная, (что вы, вероятно, будете делать для параметров командной строки в любом случае). Даже если нет параметров $argv возвращает пустой массив.

если он установлен, то cli был использован. Тогда вы можете считать все остальные вызовы через веб-сервер или другой.

например:

if (isset($argv)) {
  // Do the cli thing.
}

основе ответ серебряной Луны выше, Я использую эту функцию для возвращения правильного переносы:

/**
* 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>";

}

правильный ответ на этот вопрос зависит от реальных намерений за ним:

  • является ли SAPI решающим фактором (веб-контекст или нет)?
  • или информация интерпретируется как "работает в tty"?

Если первый ответы даны и комментарии написаны достаточно, чтобы найти решение, которое работает.

Если последнее, рецепты, приведенные здесь, потерпят неудачу, если инструмент запускается как cronjob или как фоновое задание от другого демона -- в таком случае я предлагаю дополнительно проверить, если STDIN это TTY:

function at_tty() {
    return defined("\STDIN") && posix_isatty(\STDIN);
}

Как так много сложных решений. Как насчёт...

if($_SERVER['REQUEST_SCHEME']=="http" or $_SERVER['REQUEST_SCHEME']=="https"){
    // must be browser :)
}

Я бы попробовал:

echo exec('whoami');

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

Comments

    Ничего не найдено.