确定 PHP 脚本的命令行与 http 执行的规范方法是啥?

Posted

技术标签:

【中文标题】确定 PHP 脚本的命令行与 http 执行的规范方法是啥?【英文标题】:What is the canonical way to determine commandline vs. http execution of a PHP script?确定 PHP 脚本的命令行与 http 执行的规范方法是什么? 【发布时间】:2010-09-15 11:44:08 【问题描述】:

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

【问题讨论】:

【参考方案1】:

使用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() 相同。

【讨论】:

谢谢。我很好奇为什么是医生。示例检查前 3 个字符,而描述说明字符串应该是“cgi”,但除此之外,我认为这是完美的。 当然,除非返回的字符串是 'cgi',这也表明 php 正在从控制台执行。就像,whaddayaknow,我的情况。 @Adriano:也许在你的情况下 php-cgi 用于执行脚本。 @Bobby,php.net 文档中的示例实际上仅通过查看字符串的前三个字符就可以匹配“cgi”和“cgi-fcgi”......这就是为什么而且实际上说得通。如果有的话,只是为了找回@hop 调用 php 对严肃的程序员来说没有语言:D 这里有一个有趣的注释:php.net/manual/en/function.php-sapi-name.php 是根据调用的实际二进制文件,您可以从命令行运行 php 并仍然获得 cgi-fgi【参考方案2】:

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

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

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

<?php PHP_SAPI === 'cli' or die('not allowed');

【讨论】:

你的第二个 sn-p 似乎不合逻辑,我希望 CLI or die('not allowed'); @Madbreaks,我说的是两种不同的用途。我假设 either 一个或另一个 - 但如果你同时使用两者,那么 CLI or die('not allowed'); 是完美的。 Which makes it easy to use at the top of your scripts 听起来不像是两个单独的用途。是的,我是死灵法师。【参考方案3】:

这里是 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 recommends 使用 PHP_SAPI === 'cli'

【讨论】:

【参考方案4】:

我认为

$_SERVER['REMOTE_ADDR']

不会从 CLI 填充。

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

【讨论】:

【参考方案5】:

php_sapi_name 的文档页面清楚地说明了它的工作原理:

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

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

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

另外,鲍比说:

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

示例说明:

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

【讨论】:

啊 - 要么我那天非常不注意,要么自从我发表评论后示例已经更新。不过,完全同意您关于 PHP 的观点;抨击变得非常累人。

以上是关于确定 PHP 脚本的命令行与 http 执行的规范方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

持续更新中Linux命令行与Shell脚本编程大全(第3版)读书笔记12-20章

《Linux命令行与shell脚本编程大全》第十二章 使用结构化命令

《Linux命令行与shell脚本编程大全》第十三章 更多的结构化命令

《Linux命令行与shell脚本编程大全》第二十六章 一些有意思的脚本

《Linux命令行与shell脚本编程大全》第二十一章 sed进阶

《Linux命令行与shell脚本编程大全》第十章 使用编辑器