PHP - 如何最好地确定当前调用是来自CLI还是Web服务器?
我需要确定PHP的当前调用是来自命令行(CLI)还是来自Web服务器(在我的情况下,是带有mod_php的Apache)。
任何推荐的方法?
18个解决方案
273 votes
php_sapi_name是您要使用的函数,因为它返回接口类型的小写字符串。 另外,还有PHP常量PHP_SAPI。
文档可以在这里找到:[http://php.net/php_sapi_name]
例如,要确定是否从CLI运行PHP,可以使用此函数:
functionisCommandLineInterface(){return(php_sapi_name()==='cli');}
Joe Lencioni answered 2019-04-22T21:07:03Z
22 votes
我已经使用这个功能几年了
functionis_cli(){if(defined('STDIN')){returntrue;}if(php_sapi_name()==='cli'){returntrue;}if(array_key_exists('SHELL',$_ENV)){returntrue;}if(empty($_SERVER['REMOTE_ADDR'])and!isset($_SERVER['HTTP_USER_AGENT'])andcount($_SERVER['argv'])>0){returntrue;}if(!array_key_exists('REQUEST_METHOD',$_SERVER)){returntrue;}returnfalse;}
Silver Moon answered 2019-04-22T21:07:27Z
21 votes
我认为他的意思是,如果正在调用PHP CLI,或者它是来自Web请求的响应。 最好的方法是使用php_sapi_name(),如果它正在运行Web请求,则会回显Apache,如果它正在运行的话。
列出了从php_sapi_name()上的php文档中获取的一些内容:
AOLserver的
阿帕奇
apache2filter
apache2handler
Caudium服务器
cgi(直到PHP 5.3)
CGI-FCGI
CLI
cli-server(PHP 5.4内置的Web服务器)
连续性
嵌
FPM-FCGI
ISAPI
的Litespeed
雄鱼
NSAPI
phttpd
Pi3Web服务器
Roxen的
THTTPD
晚礼服
webjames
Marc Towler answered 2019-04-22T21:10:21Z
18 votes
http_response_code()实际上不是执行此检查的最佳方法,因为它取决于检查许多可能的值。 php-cgi二进制文件可以从命令行,shell脚本或作为cron作业调用,并且(在大多数情况下)这些也应该被视为'cli',但php_sapi_name()将为这些返回不同的值(请注意,这不是 在PHP的普通版本的情况下,你希望你的代码可以在任何地方工作,对吗?)。 更不用说明年可能有新的方法来使用我们现在无法知道的PHP。 当我关心的只是天气时,我宁愿不考虑它,我应该用HTML包装我的输出。
幸运的是,PHP有办法专门检查这一点。 只使用没有任何参数的http_response_code(),如果从Web服务器类型环境运行它将返回TRUE,如果从CLI类型环境运行则返回FALSE。 这是代码:
$is_web=http_response_code()!==FALSE;
如果你在调用它之前意外地(?)从运行CLI(或类似CLI)的脚本设置响应代码,这甚至可以工作。
krowe2 answered 2019-04-22T21:11:00Z
12 votes
这应该处理所有的情况(包括php-cgi)
return(php_sapi_name()==='cli'ORdefined('STDIN'));
rbawaskar answered 2019-04-22T21:11:25Z
6 votes
functionis_cli(){return!http_response_code();}
例:
if(is_cli()){echo'command line';}else{echo'browser';}
Terry Lin answered 2019-04-22T21:11:45Z
3 votes
尝试
isset($_SERVER['REQUEST_METHOD'])
如果已设置,则您在浏览器中。
或者,你可以检查一下
isset($_SERVER['argv'])
但在Windows CLI,IDK上可能不是这样。
gnud answered 2019-04-22T21:12:24Z
3 votes
我用过这个:
php_sapi_name()=='cli'||(is_numeric($_SERVER['argc'])&&$_SERVER['argc']>0)
这是来自Drush codebase,environment.inc,它们有类似的检查。
Ranjan answered 2019-04-22T21:12:51Z
1 votes
根据[http://jp2.php.net/manual/en/features.commandline.php],只有在从CLI运行时才设置了许多常量。 这些常量是STDIN,STDOUT和STDERR。 测试其中一个将告诉您它是否处于cli模式
Jonathan Fingland answered 2019-04-22T21:13:16Z
1 votes
joomla方式
if(array_key_exists('REQUEST_METHOD',$_SERVER))die();
Sander answered 2019-04-22T21:13:40Z
0 votes
我建议检查是否设置了$ _SERVER数组的某些条目。
例如。:
if(isset($_SERVER['REQUEST_METHOD'])){print"HTTP request\n";}else{print"CLI invocation\n";}
rodion answered 2019-04-22T21:14:06Z
0 votes
我的首选方法:
if(array_key_exists('SHELL',$_ENV)){echo"Console invocation";}else{echo"HTTP invocation";}
Travis Beale answered 2019-04-22T21:14:31Z
0 votes
// Detect CLI callsdefine("IS_CLI_CALL",(strcmp(php_sapi_name(),'cli')==0));if(IS_CLI_CALL){//do you stuff here}
Hắc Huyền Minh answered 2019-04-22T21:14:49Z
0 votes
一种简单的方法是询问$argv变量(无论如何,您可能会对命令行参数执行此操作)。 即使没有参数$argv也会返回一个空数组。
如果设置,则使用cli。 然后,您可以假设所有其他调用都是通过某个Web服务器或其他。
例如:
if(isset($argv)){// Do the cli thing.}
lucsan answered 2019-04-22T21:15:22Z
0 votes
基于Silver Moon上面的答案,我正在使用此函数返回正确的换行符:
/**
* Linebreak function
* @return "/n" if cli, else return
*/protectedstaticfunctionlb(){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":"
";}
a20 answered 2019-04-22T21:15:47Z
0 votes
这个问题的正确答案取决于它背后的真正意图:
SAPI是决定因素(网络环境与否)?
或者是否将信息解释为“在tty中运行”?
如果前者给出的答案和写的评论足以找到有效的解决方案。
如果是后者,如果工具以cronjob运行,或者作为来自另一个守护进程的后台作业,此处给出的配方将失败 - 在这种情况下,我建议进一步测试STDIN是否为TTY:
functionat_tty(){returndefined("\STDIN")&&posix_isatty(\STDIN);}
Tom Regner answered 2019-04-22T21:16:39Z
0 votes
如何,这么多复杂的解决方案。 怎么样 ...
if($_SERVER['REQUEST_SCHEME']=="http"or$_SERVER['REQUEST_SCHEME']=="https"){// must be browser :)}
adrianTNT answered 2019-04-22T21:17:04Z
-14 votes
我试试:
echoexec('whoami');
通常,web服务器在不同的用户名下运行,因此应该说明。
Stefan Mai answered 2019-04-22T21:17:31Z