MyTetra Share
Делитесь знаниями!
PHP - how to best determine if the current invocation is from CLI or web server?
Время создания: 13.07.2018 15:30
Текстовые метки: php sapi cli web
Раздел: PHP
Запись: Velonski/mytetra-database/master/base/1516813830w7naevia2h/text.html на raw.githubusercontent.com

php_sapi_name is the function you will want to use as it returns a lowercase string of the interface type. In addition, there is the PHP constant PHP_SAPI.

Documentation can be found here: http://php.net/php_sapi_name

For example, to determine if PHP is being run from the CLI, you could use this function:

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

s hareimprove this answer

edited Mar 12 '12 at 5:34


community wiki


3 revs, 3 users 44%
Joe Lencioni

8

 

More straightforward: return php_sapi_name() == 'cli'; – Savageman Aug 9 '10 at 19:18

9

 

I did a research: if you invoke the script with php-cgi this won't work. In turn, it will return cgi-fcgi String. If you load the script as a web page from a browser, you'll get apache2handler. Hope this helps. I needed to use php-cgi in order to introduce $_GET variables: php-cgi myscript.php arg1=one arg2=two. Testing for not equal to apache2handler should be ok for apache. – Sebastian Jun 12 '13 at 1:01

2

 

A small caveat about this method: it will not return "cli" when run from a cron job. There's a number od differents keys to choose from inside of $_SERVER to determine more reliably whether the request came via HTTP or not. – omninonsense Jun 3 '16 at 8:00

add a comment


up vote 20 down vote

I think he means if PHP CLI is being invoked or if it is a response from a web request. The best way would be to use php_sapi_name() which if it was running a web request would echo Apache if that is what it was running.

To list of a few taken from the php docs on php_sapi_name() :

  • aolserver
  • apache
  • apache2filter
  • apache2handler
  • caudium
  • cgi (until PHP 5.3)
  • cgi-fcgi
  • cli
  • cli-server (Built-in web server as of PHP 5.4)
  • continuity
  • embed
  • fpm-fcgi
  • isapi
  • litespeed
  • milter
  • nsapi
  • phttpd
  • pi3web
  • roxen
  • thttpd
  • tux
  • webjames

s hareimprove this answer

edited Aug 8 '15 at 6:23


community wiki


3 revs, 2 users 69%
Marc Towler

add a comment


up vote 11 down vote

This should handle all the cases (including php-cgi)

return (php_sapi_name() === 'cli' OR defined('STDIN')); 

s hareimprove this answer

answered Jan 17 '14 at 11:22


community wiki


r bawaskar

add a comment


up vote 11 down vote

I have been using this function for a few years

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

Let me know what you think

s hareimprove this answer

edited Oct 26 '16 at 14:50


community wiki


3 revs, 3 users 63%
Silver Moon

7

 

array_key_exists('REQUEST_METHOD', $_SERVER) return true; WAT? – biziclop Mar 1 '16 at 22:42

  

 

@biziclop, the check for array_key_exists('REQUEST_METHOD', $_SERVER) is correct to assist the detection of the source of the request. When in CLI, the $_SERVER Super Global array WILL NOT HAVE the key REQUEST_METHOD, it only exists when the request is made via Web, hence, the author is absolutely on target when checking for it. – Julio Marchi Sep 14 '16 at 7:28

1

 

@JulioMarchi: but shouldn't it return false; or do if ( ! array_key_exists(…)) return true;? – biziclop Sep 14 '16 at 15:20

2

 

@biziclop, you are entirely right!!!! How could I miss such enormous small detail??? Shame on me... :). Surely, if the KEY 'REQUEST_METHOD' is NOT found, then the function should return FALSE to indicate "CLI". My apologies for not paying attention to the scope of the function itself... The author should fix it because the function actually works! – Julio Marchi Sep 18 '16 at 7:37

add a comment


up vote 9 down vote

php_sapi_name() is really not the best way to perform this check because it depends on checking against many possible values. The php-cgi binary can be called from the command line, from a shell script or as a cron job and (in most cases) these should also be treated as 'cli' but php_sapi_name() will return different values for these (note that this isn't the case with the plain version of PHP but you want your code to work anywhere, right?). Not to mention that next year there may be new ways to use PHP that we can't possibly know now. I'd rather not think about it when all I care about is weather I should wrap my output in HTML or not.

Fortunately, PHP has a way to check for this specifically. Just use http_response_code() without any parameters and it'll return TRUE if ran from a web server type environment and FALSE if ran from a CLI type environment. Here is the code:

$is_web=http_response_code()!==FALSE; 

This will even work if you accidentally(?) set a response code from a script running from the CLI (or something like the CLI) before you call this.

s hareimprove this answer

edited Dec 30 '16 at 22:16


community wiki


2 revs
krowe2

1

 

You're right but why no one voted for your answer? – Terry Lin Feb 15 '17 at 10:30

2

 

This question was already old when I answered it. Up-voting this answer would've probably been more useful than posting another answer that is a duplicate except without the explanation. – krowe2 Feb 15 '17 at 15:49

add a comment


up vote 6 down vote

function is_cli() {
    return !http_response_code();
} 

example:

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

s hareimprove this answer

edited Feb 15 '17 at 18:06


community wiki


2 revs, 2 users 95%
Terry Lin

2

 

From the manual, "FALSE will be returned if response_code is not provided and it is not invoked in a web server environment (such as from a CLI application). TRUE will be returned if response_code is provided and it is not invoked in a web server environment (but only when no previous response status has been set)". You've gotten your logic backwards. – krowe2 Feb 15 '17 at 16:04

1

 

+1. Amazing. After so many years of fruitless research... I hereby award you the Nobel Memorial Prize in PHPics, shared with @krowe2 for his invaluable contribution of actually making it work. Congratulations! – Sz. Feb 15 '17 at 18:14

add a comment


up vote 3 down vote

Try

isset($_SERVER['REQUEST_METHOD']) 

if it's set, you're in a browser.

Alternatlely, you could check if

isset($_SERVER['argv']) 

but that might not be true on windows CLI, IDK.

s hareimprove this answer

answered Jun 1 '09 at 2:33


community wiki


g nud

1

 

Though it is not the "correct" answer it might be the more reliable – challet Oct 4 '16 at 11:56

add a comment


up vote 3 down vote

I used this:

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

This is from Drush codebase, environment.inc where they have similar check to make.

s hareimprove this answer

answered Apr 16 '13 at 18:48


community wiki


R anjan

3

 

If register_argc_argv is set, then passing in any amount of GET values will cause argc to not be 0. – simon_w Jul 17 '14 at 8:23

add a comment


up vote 1 down vote

According to http://jp2.php.net/manual/en/features.commandline.php There are a number of constants set only when running from the CLI. These constants are STDIN, STDOUT and STDERR. Testing for one of those will tell you if it is in cli mode

s hareimprove this answer

answered Jun 1 '09 at 2:36


community wiki


J onathan Fingland

add a comment


up vote 0 down vote

I would suggest to check if some of the entries of the $_SERVER array are set.

E.g.:

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

s hareimprove this answer

answered Jun 1 '09 at 2:34


community wiki


r odion

  

 

This won't work with php-cgi command line, it will set it to GET for: php-cgi -f file.php arg1=2 – Sebastian Jun 14 '13 at 23:57

  

 

@Sebastian thanks for the observation – Silver Moon Sep 22 '14 at 5:55

add a comment


up vote 0 down vote

My preferred method:

if (array_key_exists('SHELL', $_ENV)) {
  echo "Console invocation";
}
else {
  echo "HTTP invocation";
} 

s hareimprove this answer

answered Jun 1 '09 at 14:45


community wiki


T ravis Beale

  

 

This won't work with php-cgi command line. – Sebastian Jun 14 '13 at 20:53

add a comment


up vote 0 down vote

// Detect CLI calls
define("IS_CLI_CALL",( strcmp(php_sapi_name(),'cli') == 0 ));

if(IS_CLI_CALL){
   //do you stuff here

} 

s hareimprove this answer

answered Oct 22 '13 at 8:55


community wiki


H ắc Huyền Minh

add a comment


up vote 0 down vote

joomla way

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

s hareimprove this answer

answered Sep 2 '14 at 12:57


community wiki


S ander

add a comment


up vote 0 down vote

An easy way is to interrogate the $argv variable, (Which you will probably do for command line parameters anyway). Even if there are no parameters $argv returns an empty array.

If it is set, then cli was used. You may then assume all other invocations are via some web server or other.

eg:

if (isset($argv)) {
  // Do the cli thing.
} 
 
MyTetra Share v.0.59
Яндекс индекс цитирования