首页 文章

PHP - 如何最好地确定当前调用是来自CLI还是Web服务器?

提问于
浏览
161

我需要确定PHP的当前调用是来自命令行(CLI)还是来自Web服务器(在我的情况下,是带有mod_php的Apache) .

任何推荐的方法?

18 回答

  • 0

    一种简单的方法是询问 $argv 变量(无论如何,您可能会对命令行参数执行此操作) . 即使没有参数, $argv 也会返回一个空数组 .

    如果设置,则使用cli . 然后,您可以假设所有其他调用都是通过某个Web服务器或其他 .

    例如:

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

    基于Silver Moon's answer above,我正在使用此函数返回正确的换行符:

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

    php_sapi_name 是您要使用的函数,因为它返回接口类型的小写字符串 . 另外,还有PHP常量 PHP_SAPI .

    文档可以在这里找到:http://php.net/php_sapi_name

    例如,要确定是否从CLI运行PHP,可以使用此函数:

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

    我已经使用这个功能几年了

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

    我认为他的意思是,如果正在调用PHP CLI,或者它是来自Web请求的响应 . 最好的方法是使用 php_sapi_name() ,如果它正在运行Web请求,则会回显Apache,如果它正在运行的话 .

    列出一些取自php docs on php_sapi_name()

    • aolserver

    • apache

    • apache2filter

    • apache2handler

    • caudium

    • cgi(直到PHP 5.3)

    • cgi-fcgi

    • cli

    • cli-server(自PHP 5.4起Built-in web server

    • 连续性

    • 嵌入

    • fpm-fcgi

    • isapi

    • litespeed

    • milter

    • nsapi

    • phttpd

    • pi3web

    • 罗克森

    • thttpd

    • 晚礼服

    • 网络游戏

  • 1

    php_sapi_name() 实际上不是执行此检查的最佳方法,因为它取决于检查许多可能的值 . php-cgi二进制文件可以从命令行,从shell脚本或作为cron作业调用,并且(在大多数情况下)这些也应该被视为'cli'但 php_sapi_name() 将为这些返回不同的值(请注意,这不是'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我现在可能知道了 . 当我关心的只是天气时,我宁愿不考虑它,我应该用HTML包装我的输出 .

    幸运的是,PHP有办法专门检查这一点 . 只使用没有任何参数的 http_response_code() 如果从Web服务器类型环境运行它将返回TRUE,如果从CLI类型环境运行则返回FALSE . 这是代码:

    $is_web=http_response_code()!==FALSE;
    

    如果你在调用它之前意外地(?)从运行CLI(或类似CLI)的脚本设置响应代码,这甚至可以工作 .

  • 22

    这应该处理所有的情况(包括php-cgi)

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

    例:

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

    尝试

    isset($_SERVER['REQUEST_METHOD'])
    

    如果已设置,则您在浏览器中 .

    或者,你可以检查一下

    isset($_SERVER['argv'])
    

    但在Windows CLI,IDK上可能不是这样 .

  • 6

    我用过这个:

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

    这是来自Drush codebase,environment.inc,它们有类似的检查 .

  • 0

    根据http://jp2.php.net/manual/en/features.commandline.php仅在从CLI运行时设置了许多常量 . 这些常量是STDIN,STDOUT和STDERR . 测试其中一个将告诉您它是否处于cli模式

  • 0

    joomla方式

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

    我建议检查是否设置了$_SERVER数组的某些条目 .

    例如 . :

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

    我的首选方法:

    if (array_key_exists('SHELL', $_ENV)) {
      echo "Console invocation";
    }
    else {
      echo "HTTP invocation";
    }
    
  • 3
    // Detect CLI calls
    define("IS_CLI_CALL",( strcmp(php_sapi_name(),'cli') == 0 ));
    
    if(IS_CLI_CALL){
       //do you stuff here
    
    }
    
  • 21

    这个问题的正确答案取决于它背后的真正意图:

    • SAPI是决定因素(网络环境与否)?

    • 或者是解释为'running in a tty'的信息?

    如果前者给出的答案和写的评论足以找到有效的解决方案 .

    如果是后者,如果工具以cronjob运行,或者作为来自另一个守护进程的后台作业,此处给出的配方将失败 - 在这种情况下,我建议进一步测试 STDIN 是否为TTY:

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

    如何,这么多复杂的解决方案 . 怎么样 ...

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

    我试试:

    echo exec('whoami');
    

    通常,web服务器在不同的用户名下运行,因此应该说明 .

相关问题