현재 호출이 CLI 또는 웹 서버에서 온 것인지 가장 잘 판단하는 방법은 무엇입니까?


답변:


308

php_sapi_name인터페이스 유형의 소문자 문자열을 반환하므로 사용하려는 함수입니다. 또한 PHP 상수가 PHP_SAPI있습니다.

http://php.net/php_sapi_name 에서 설명서를 찾을 수 있습니다.

예를 들어 CLI에서 PHP가 실행 중인지 확인하려면이 함수를 사용할 수 있습니다.

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

11
더 솔직한 :return php_sapi_name() == 'cli';
Savageman

11
나는 연구를했다 : 만약 당신이 스크립트를 호출하면 php-cgi작동하지 않습니다. 차례로 cgi-fcgiString 을 반환 합니다. 브라우저에서 스크립트를 웹 페이지로로드하면가 나타납니다 apache2handler. 도움이 되었기를 바랍니다. 변수 php-cgi를 도입하기 위해 사용해야 했습니다 . 같지 않은 테스트는 괜찮습니다 . $_GETphp-cgi myscript.php arg1=one arg2=twoapache2handlerapache
Sebastian

3
이 방법에 대한 작은 경고 : cron 작업에서 실행될 때 반환 되지 않습니다"cli" . $_SERVER요청이 HTTP를 통해 왔는지 여부를보다 확실하게 결정하기 위해 내부에서 선택할 수있는 여러 가지 키가 있습니다 .
omninonsense 2016 년

2
@omninonsense PHP 7.2.7로 테스트했으며 cli를 반환합니다.
Jose Nobile

38

이 기능을 몇 년 동안 사용해 왔습니다

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

10
array_key_exists('REQUEST_METHOD', $_SERVER) return true;와트?
biziclop

@biziclop, 요청 소스를array_key_exists('REQUEST_METHOD', $_SERVER) 감지하는 데 도움이 되는 점검 이 정확합니다 . 의 경우 CLI 는 슈퍼 글로벌 배열 것 NOT 키를 가질 , 그것은 단지 요청이 웹을 통해 이루어 될 때 검사 할 때, 따라서 저자는 대상에 절대적으로 존재한다. $_SERVERREQUEST_METHOD
Julio Marchi

1
@JulioMarchi :하지만 안 return false;나하지 if ( ! array_key_exists(…)) return true;?
biziclop

2
@biziclop, 당신은 전적으로 맞습니다 !!!! 어떻게 거대한 세부 사항을 놓칠 수 있습니까 ??? 수치심 ... :). 키가 있다면 분명 'REQUEST_METHOD'있다 NOT 발견, 다음 함수는 반환해야 FALSE"CLI"를 나타냅니다. 함수 자체의 범위에주의를 기울이지 않은 것에 대해 사과드립니다 ... 함수가 실제로 작동하기 때문에 저자가 수정해야합니다!
Julio Marchi

이 함수는 웹 요청과 cronjob 실행을 구별해야했기 때문에 php_sapi_name ()이 아닌 제 경우에는 효과가 있었으며, php_sapi_name () 결과는 두 경우 모두 "php-cgi"였습니다.
luis.ap.uyen

36

php_sapi_name()이 검사를 수행하는 가장 좋은 방법은 아닙니다. 가능한 많은 값에 대한 검사에 의존하기 때문입니다. php-cgi 바이너리는 커맨드 라인, 쉘 스크립트 또는 크론 작업으로 호출 할 수 있으며 (대부분의 경우) 이것들은 'cli'로 취급되어야하지만 php_sapi_name()이것들에 대해 다른 값을 반환합니다 (이것은 일반 버전의 PHP에서는 그렇지 않지만 코드가 어디서나 작동하기를 원하십니까?). 내년에는 말할 것도없이 현재로서는 알 수없는 PHP를 사용하는 새로운 방법이있을 수 있습니다. 내가 관심있는 모든 것이 날씨 인 경우 HTML로 출력을 래핑 해야하는지 여부에 대해 생각하지 않습니다.

다행히도 PHP는이를 구체적으로 확인할 수있는 방법이 있습니다. http_response_code()매개 변수없이 사용 하면 웹 서버 유형 환경에서 실행되면 TRUE를, CLI 유형 환경에서 실행하면 FALSE를 반환합니다. 코드는 다음과 같습니다.

$is_web=http_response_code()!==FALSE;

호출하기 전에 실수로 CLI (또는 CLI와 같은 스크립트)에서 실행되는 스크립트에서 응답 코드를 설정 한 경우에도 작동합니다.


4
이 질문은 내가 대답했을 때 이미 오래되었습니다. 이 답변을 찬성 투표하면 설명이없는 경우를 제외하고 중복 된 다른 답변을 게시하는 것보다 유용 할 것입니다.
krowe2

"이것을 호출하기 전에 실수로 CLI에서 실행되는 스크립트 ([...])에서 응답 코드를 설정 한 경우에도 작동합니다.": (최소한) PHP 7.4.3부터 사실이 아니다. http_response_code()CLI에서 실행할 때 코드를 설정 / 설정 코드를 반환합니다. 님이 확인했습니다 <?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();. 그렇다면 http_response_code()===falseCLI를 가정하는 것이 안전하지만 다른 메트릭도 확인해야합니다.
Sebastian B.

23

PHP CLI가 호출 중이거나 웹 요청의 응답인지 여부를 의미한다고 생각합니다. 가장 좋은 방법은 php_sapi_name()웹 요청을 실행중인 경우 Apache가 실행중인 경우 Apache를 에코하는 것입니다.

PHP 문서에서php_sapi_name() 가져온 몇 가지를 나열하려면 다음을 수행하십시오 .

  • aolserver
  • 아파치
  • 아파치
  • 아파치
  • 카우 디움
  • cgi (PHP 5.3까지)
  • cgi-fcgi
  • cli
  • cli-server ( PHP 5.4 현재 내장 웹 서버 )
  • 연속성
  • 끼워 넣다
  • fpm-fcgi
  • 이사 피
  • 광속
  • 밀터
  • nsapi
  • phttpd
  • pi3web
  • 록센
  • thttpd
  • 턱시도
  • 웹 제임스

13

이것은 모든 경우를 처리해야합니다 (php-cgi 포함)

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

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

예:

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

2
매뉴얼에서 "response_code가 제공되지 않고 FALSE는 웹 서버 환경 (예 : CLI 응용 프로그램)에서 호출되지 않으면 리턴됩니다. response_code가 제공되고 웹 서버에서 호출되지 않으면 TRUE가 리턴됩니다. 환경 (이전 응답 상태가 설정되지 않은 경우에만) " 당신은 당신의 논리를 거꾸로 얻었습니다.
krowe2

1
+1. 놀랄 만한. 수년간의 무실 한 연구 끝에 ... 여기서 PHPics의 노벨 기념상을 수상했습니다. 실제로 @ krowe2와 공유하여 실제로 작동하게 만드는 데 귀중한 공헌을했습니다. 축하합니다!
Sz.

무언가가 응답 코드를 설정했을 수도 있습니다 ... http_response_code(200);... 지금 전화 http_response_code()하면 200을 반환합니다.
브래드 켄트

@BradKent 웹 환경에서 이것을 호출하는 경우에만 해당되며,이 경우 상태 코드를 0으로 설정하지 않는 한 (이는 잘못된 HTTP 상태 코드 임)이 검사는 계속 작동합니다. 내 버전은 FALSE에 대해 구체적으로 검사하기 때문에이 경우에도 작동합니다. 경우 http_response_code();CLI를 환경에서 호출 항상 실제 상태 코드에 관계없이 FALSE를 반환합니다. 나는 이미 내 대답에서 이것을 설명했지만 "값 반환"의 매뉴얼 페이지를 읽거나 시도하여 이것을 찾을 수 있습니다.
krowe2

@ krowe2는 php -r 'http_response_code(200); echo http_response_code()."\n";' "200"을 출력한다. 어떤 라이브러리 나 무지한 프레임 워크가 http_response_code(cli env에서도) 응답 코드를 설정하지 않았다고 보장 할 수 없다면 , 이것이 작동 할 것이다. 개인적으로 사용합니다$isCli = \defined('STDIN') || isset($_SERVER['argv']) || \array_key_exists('REQUEST_METHOD', $_SERVER)
Brad Kent

4

나는 이것을 사용했다 :

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

이것은 Drush 코드베이스, environment.inc에서 가져온 것입니다.


4
경우 register_argc_argv설정, 다음 GET 값의 양을 전달하는 원인이됩니다 argc0이하지

3

시험

isset($_SERVER['REQUEST_METHOD'])

설정되어 있으면 브라우저에있는 것입니다.

또는, 당신은 여부를 확인할 수 있습니다

isset($_SERVER['argv'])

그러나 Windows CLI, IDK에서는 그렇지 않을 수 있습니다.


1
그것은 "올바른"은 아니지만 그것이 더 신뢰할 수 있습니다 답변
challet


2

줌라 웨이

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

0

$ _SERVER 배열 의 일부 항목 이 설정 되어 있는지 확인하는 것이 좋습니다 .

예 :

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

php-cgi명령 행에서는 작동하지 않으며 다음과 같이 설정됩니다 GET.php-cgi -f file.php arg1=2
Sebastian

0

내가 선호하는 방법 :

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

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

if(IS_CLI_CALL){
   //do you stuff here

}

0

쉬운 방법은 $argv변수 를 조사하는 것입니다 (어쨌든 명령 행 매개 변수에 대해 수행 할 것임). 매개 변수가 없어도 $argv빈 배열을 반환합니다.

설정된 경우 cli가 사용되었습니다. 그런 다음 다른 모든 호출이 일부 웹 서버 또는 다른 서버를 통한 것이라고 가정 할 수 있습니다.

예 :

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

0

위의 Silver Moon의 답변을 기반 으로 올바른 줄 바꿈을 반환하기 위해이 기능을 사용하고 있습니다.

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

}

0

이 질문에 대한 정답은 그 뒤에 숨겨진 의도에 달려 있습니다.

  • SAPI가 결정 요인 (웹 컨텍스트인지 아닌지)입니까?
  • 아니면 정보가 'tty에서 실행'으로 해석됩니까?

전자의 경우 주어진 답변과 작성된 의견만으로도 효과적인 솔루션을 찾을 수 있습니다.

후자가 도구가 cronjob 또는 다른 데몬에서 백그라운드 작업으로 실행되면 여기에 제공된 레시피가 실패합니다.이 경우 STDINTTY 인지 추가 테스트하는 것이 좋습니다 .

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

-1

어떻게, 많은 복잡한 솔루션. 어때요 ...

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

-18

나는 시도 할 것이다 :

echo exec('whoami');

일반적으로 웹 서버는 다른 사용자 이름으로 실행되므로 알 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.