我需要确定当前对PHP的调用是来自命令行(CLI)还是来自web服务器(在我的情况下,使用mod_php的Apache)。
有什么推荐方法吗?
我需要确定当前对PHP的调用是来自命令行(CLI)还是来自web服务器(在我的情况下,使用mod_php的Apache)。
有什么推荐方法吗?
当前回答
我用了这个:
php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)
这是来自Drush代码库,环境。公司也有类似的检查。
其他回答
joomla的方式
if (array_key_exists('REQUEST_METHOD', $_SERVER)) die();
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.
幸运的是,PHP有一种方法可以检查这一点。只需使用http_response_code(),不带任何参数,如果从web服务器类型环境运行,它将返回TRUE,如果从CLI类型环境运行,则返回FALSE。代码如下:
$is_web=http_response_code()!==FALSE;
即使您在调用之前不小心(?)从从CLI(或类似CLI的东西)运行的脚本设置了响应代码,这也可以工作。
这个问题的正确答案取决于它背后的真正意图:
SAPI是决定因素吗(web-context或者不是)? 或者该信息被解释为“运行在tty中”?
如果是前者,给出的答案和写下的评论就足以找到一个有效的解决方案。
如果是后者,这里给出的食谱将失败,如果工具作为cronjob运行,或作为来自另一个守护进程的后台作业运行——在这种情况下,我建议进一步测试STDIN是否为TTY:
function at_tty() {
return defined("\STDIN") && posix_isatty(\STDIN);
}
基于银月的答案上面,我使用这个函数返回正确的换行:
/**
* 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>";
}
一个实用的提示
官方的方式(正如许多人所说)是PHP_SAPI作为一个常量,或php_sapi_name()作为一个函数,当您在命令行情况下,它们都返回cli。他们是对的。
但是!…
考虑使用$_SERVER["argv"](在大多数情况下也是$argv),当你在浏览器中运行时它是空的,当你从命令行调用时它是一个数组。这种方法(或两者都使用)的优点是,通过给$argv / $_SERVER["argv"]变量赋一个(假的)值,可以模拟在浏览器中运行的终端。当您在通常无法获得SSH访问的外部服务器(prod、staging等)上进行测试时,这非常方便。
做到这一点的最好方法是记住你是否需要CLI模拟,并使用$argv和PHP_SAPI来协调这一点-例如,如果PHP_SAPI不是“CLI”,而$argv有一个值,你可能需要事先输出一个额外的<pre>标签。