163

我有一个 PHP 脚本,需要确定它是通过命令行还是通过 HTTP 执行的,主要用于输出格式化目的。这样做的规范方法是什么?我原以为是要检查SERVER['argc'],但事实证明这是填充的,即使使用“Apache 2.0 处理程序”服务器 API 也是如此。

4

5 回答 5

240

使用该php_sapi_name()功能。

if (php_sapi_name() == "cli") {
    // In cli-mode
} else {
    // Not in cli-mode
}

以下是文档中的一些相关说明:

php_sapi_name — 返回 Web 服务器和 PHP 之间的接口类型

尽管并非详尽无遗,但可能的返回值包括 aolserver、apache、apache2filter、apache2handler、caudium、cgi(直到 PHP 5.3)、cgi-fcgi、cli、cli-server、continuity、embed、isapi、litespeed、milter、nsapi、phttpd、 pi3web、roxen、thttpd、tux 和 webjames。

在 PHP >= 4.2.0 中,还有一个预定义常量 ,PHP_SAPI它的值与php_sapi_name().

于 2008-10-06T11:07:22.160 回答
23

这将始终有效。(如果 PHP 版本是 4.2.0 或更高版本)

define('CLI', PHP_SAPI === 'cli');

这使得在脚本顶部易于使用:

<?php PHP_SAPI === 'cli' or die('not allowed');
于 2010-12-08T22:08:38.547 回答
10

这是 Drupal 7 的实现:drupal_is_cli()

function drupal_is_cli() {
  return (!isset($_SERVER['SERVER_SOFTWARE']) && (php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)));
}

但是 Drupal 8建议使用PHP_SAPI === 'cli'

于 2012-09-29T17:36:42.713 回答
9

我认为

$_SERVER['REMOTE_ADDR']

不会从 CLI 填充。

此外,$_SERVER 超全局变量中的所有 HTTP_* 键都不会从 CLI 中填充,或者按照刚才提到的正确方式进行操作 :-)

于 2008-10-06T10:53:32.190 回答
5

php_sapi_name的文档页面清楚地说明了它是如何工作的:

返回描述 PHP 正在使用的接口类型(服务器 API、SAPI)的小写字符串。

虽然并不详尽,但可能的返回值包括 aolserver、apache、apache2filter、apache2handler、caudium、cgi(直到 PHP 5.3)、cgi-fcgi、cli、continuity、embed、isapi、litespeed、milter、nsapi、phttpd、pi3web、roxen、 thttpd、tux 和 webjames。

我不确定为什么 hop 认为 PHP 不适合认真的程序员(我是认真的程序员,我每天都使用 PHP),但如果他想帮助澄清文档,那么也许他可以审核所有可能的 Web 服务器PHP 可以在其上运行并确定每个服务器的所有可能接口类型的名称。只要确保在添加新的 Web 服务器和接口时更新该列表即可。

此外,鲍比说:

我很好奇为什么是医生。示例检查前 3 个字符,而描述说明该字符串应完全为“CGI”

该示例的描述指出:

此示例检查子字符串 cgi,因为它也可能是 cgi-fcgi。

于 2009-08-05T18:51:14.570 回答