Який канонічний спосіб визначити виконання командного рядка проти http-скрипту PHP?


155

У мене є скрипт PHP, який повинен визначити, чи виконується він через командний рядок або через HTTP, головним чином для цілей форматування виводу. Який канонічний спосіб зробити це? Я думав, що слід перевірити SERVER['argc'], але виявляється, що це заповнюється, навіть коли використовується серверний API 'Apache 2.0 Handler'.

Відповіді:


228

Використовуйте 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-сервер, безперервність, embed, isapi, litespeed, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux та webjames.

У PHP> = 4.2.0 також є заздалегідь визначена константа PHP_SAPI, яка має те саме значення, що і php_sapi_name().


Дякую. Мене заінтригує, чому док. Приклад перевіряє перші 3 символи, в той час як в описі зазначено, що рядок повинен бути точно "cgi", але, крім цього, я думаю, що це ідеально.
Боббі Джек

якщо, звичайно, повернута рядок не була 'cgi', що також вказує на те, що php виконується з консолі. Як і в, але, мій випадок.
Адріано Варолі П'яцца

@Adriano: можливо, у вашому випадку для виконання сценарію використовується php-cgi.

3
@Bobby, приклад у документах php.net насправді відповідає як "cgi", так і "cgi-fcgi", лише дивлячись на перші три символи рядка ... саме тому і це насправді має сенс. Якщо що-небудь, то просто повернутися @hop для виклику php без мови для серйозних програмістів: D
ChrisR

1
Цікава зауваження тут: php.net/manual/en/function.php-sapi-name.php полягає в тому, що залежно від фактичного виклику бінарних файлів, ви можете запустити php з командного рядка і все-таки отримати cgi-fgi
DAB

22

Це завжди буде працювати. (Якщо версія PHP становить 4.2.0 або вище)

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

Що дозволяє легко використовувати у верхній частині сценаріїв:

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

8
Ваш другий фрагмент здається не послідовним, я б очікувавCLI or die('not allowed');
Madbreaks

1
@Madbreaks, я констатував два різних використання. Я припускав , або один або інший , - але якщо ви використовуєте і потім CLI or die('not allowed');досконалий.
Xeoncross

Дякуємо за уточнення, +1
Madbreaks

7
Which makes it easy to use at the top of your scriptsнасправді це не звучить як два окремих використання. Так, я некроман.
Джордж Димитріадіс

9

Ось реалізація 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'


8

Я думаю

$_SERVER['REMOTE_ADDR']

не буде заповнено з CLI.

Крім того, всі клавіші HTTP_ * у суперглобалі $ _SERVER не будуть заповнені з CLI, або робити це правильно, як тільки що згадано :-)


4

На сторінці документації для php_sapi_name чітко зазначено, як вона працює:

Повертає рядку з малих літер, що описує тип інтерфейсу (API сервера, SAPI), який PHP використовує ....

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

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

Також Боббі сказав:

Мене заінтригує, чому док. приклад перевіряє перші 3 символи, в той час як в описі зазначено, що рядок повинен бути точно "CGI"

В описі прикладу зазначено:

Цей приклад перевіряє наявність підрядкової cgi, оскільки вона може бути також cgi-fcgi.


Ага - або я був у той день неймовірно непомітний, або приклад оновлювався, оскільки я зробив цей коментар. Хоча від усієї думки погоджуєтесь з вашими пунктами щодо PHP; базінг стає ДУЖЕ стомлюючим.
Боббі Джек
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.