我需要确定当前对PHP的调用是来自命令行(CLI)还是来自web服务器(在我的情况下,使用mod_php的Apache)。

有什么推荐方法吗?


当前回答

我用了这个:

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

这是来自Drush代码库,环境。公司也有类似的检查。

其他回答

Try

isset($_SERVER['REQUEST_METHOD'])

如果设置了,则是在浏览器中。

或者,你可以检查是否

isset($_SERVER['argv'])

但在windows CLI、IDK上可能不是这样。

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

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

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

SAPI是决定因素吗(web-context或者不是)? 或者该信息被解释为“运行在tty中”?

如果是前者,给出的答案和写下的评论就足以找到一个有效的解决方案。

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

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

一个实用的提示

官方的方式(正如许多人所说)是PHP_SAPI作为一个常量,或php_sapi_name()作为一个函数,当您在命令行情况下,它们都返回cli。他们是对的。

但是!…

考虑使用$_SERVER["argv"](在大多数情况下也是$argv),当你在浏览器中运行时它是空的,当你从命令行调用时它是一个数组。这种方法(或两者都使用)的优点是,通过给$argv / $_SERVER["argv"]变量赋一个(假的)值,可以模拟在浏览器中运行的终端。当您在通常无法获得SSH访问的外部服务器(prod、staging等)上进行测试时,这非常方便。

做到这一点的最好方法是记住你是否需要CLI模拟,并使用$argv和PHP_SAPI来协调这一点-例如,如果PHP_SAPI不是“CLI”,而$argv有一个值,你可能需要事先输出一个额外的<pre>标签。

基于银月的答案上面,我使用这个函数返回正确的换行:

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

}