php - 为什么 PHP CLI 被视为 SAPI 的一种?

标签 php

根据维基百科的定义:

In other words, SAPI is actually an application programming interface (API) provided by the web server to help other developers in extending the web server capabilities.

Different kinds of SAPIs exist for various web-server extensions. For example, in addition to those listed above, other SAPIs for the PHP language include the Common Gateway Interface (CGI) and command-line interface (CLI).

但是,我认为当通过终端(命令行)运行 php 文件或使用 php-cli 交互式 shell 时,只有 zend 引擎会参与解释代码。

有什么我错了或者不知道的事情吗?

难道是因为通过Web服务器与客户端交互?



编辑:除了接受的答案之外,为了更好地理解该主题的进一步解释:

Advanced PHP Programming作者:乔治·施洛斯纳格

enter image description here

PHP 与其他应用程序交互的最外层是服务器抽象 API (SAPI) 层。 SAPI 层部分处理应用程序内 PHP 的启动和关闭,并提供用于以与应用程序无关的方式处理 cookie 和 POST 数据等数据的钩子(Hook)。

SAPI 层下面是 PHP 引擎本身。核心 PHP 代码负责设置运行环境(填充全局变量和设置默认 .ini 选项),提供流的 I/O 接口(interface)、数据解析等接口(interface),最重要的是提供加载扩展的接口(interface)(都是静态的)编译的扩展和动态加载的扩展)。

PHP 的核心是 Zend 引擎,我们已经在这里深入讨论过。正如您所看到的,Zend 引擎完全处理脚本的解析和执行。 Zend 引擎还设计了可扩展性,并允许完全重写其基本功能(编译、执行和错误处理)、重写其行为的选择性部分(重写特定操作中的 op_handlers)以及在可注册 Hook 上调用函数(在每个函数调用,每个操作码,等等)。这些功能允许轻松集成缓存、分析器、调试器和语义更改扩展。

SAPI 层

SAPI 层是抽象层,允许将 PHP 轻松嵌入到其他应用程序中。一些 SAPI 包括以下内容:

  • mod_php5 这是 Apache 的 PHP 模块,它是一个 SAPI 将 PHP 嵌入到 Apache Web 服务器中。

  • fastcgi 这是 FastCGI 的实现,提供可扩展的 CGI 标准的扩展。 FastCGI 是一个持久的 CGI 守护进程 可以处理多个请求。 FastCGI 是首选方法 在 IIS 下运行 PHP 并显示性能几乎与 mod_php5。

  • CLI 这是用于运行 PHP 脚本的独立解释器 命令行,它是 SAPI 层的薄包装。

  • 嵌入 这是一个通用 SAPI,旨在提供 C 用于在任意环境中嵌入 PHP 解释器的库接口(interface) 应用程序。

这个想法是,无论应用程序如何,PHP 都需要在许多常见位置与应用程序进行通信,因此 SAPI 接口(interface)为每个位置提供了一个钩子(Hook)。例如,当应用程序需要启动 PHP 时,它会调用启动 Hook 。相反,当 PHP 想要输出信息时,它使用提供的 ub_write 钩子(Hook),SAPI 层作者已对其进行编码,以便为运行 PHP 的应用程序使用正确的输出方法。

Read more

最佳答案

“为什么”始终是一个难以捉摸的、有点哲学性的问题;最终,“为什么 CLI 被视为 SAPI”的答案是“因为开发人员就是这样定义它的”。如果他们将其称为“CLI 模式”,您还会问“为什么”吗?

但你确实问了一个更具体的问题,可以解释为:

When running a program on the CLI, why do you need a SAPI as well as the Zend Engine?

或者更简洁地说:

What does the CLI SAPI do?

Zend 引擎本身接受一系列指令并执行它们。它可以管理变量、算术、函数定义和调用、类定义等等。但是,如果您无法从程序中获得任何输出,那么这些都没有什么用处。最常见的是您还想提供一些变量输入。

某些形式的输入和输出仅基于您运行的操作系统,而不是 SAPI - 基于绝对路径读取或写入文件,或通过网络连接访问某些内容。理论上你可以有一个运行模式,只允许访问这些,但它会感觉非常有限。 (这仍然是“SAPI”吗?绝对是一个哲学问题。)

考虑像 echo 这样常见的东西:Zend 引擎可以直接管理的“输出”没有绝对的定义。在 Web 服务器上下文中,您希望 echo 向服务器发送给客户端的 HTTP 响应添加一些输出;在命令行上下文中,您希望它在运行命令的控制台中显示输出,或者如果您运行类似 php foo.php | 的内容,则“通过管道”连接到另一个命令。 grep 错误

CLI SAPI 不提供与 Web 服务器 SAPI 相同的功能,但它在将在 Zend Engine 中运行的程序与外部世界连接方面发挥着类似的作用。以下是它需要做的一些事情:

  • 将输出附加到父控制台或“标准输出”流
  • 使“标准输入”和“标准错误”流可用
  • 根据调用脚本的参数填充 $argv$argc
  • 使用进程继承的环境变量填充$_ENV
  • 定义“当前工作目录”的初始值以与相对文件路径一起使用

关于php - 为什么 PHP CLI 被视为 SAPI 的一种?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61166659/

相关文章:

php - 同一页面上的多星评论

php - 使用 composer 和 PuTTY 安装 Paypal PHP SDK

php - 如何在 woocommerce 中为购物车创建自定义折扣

php - 我需要一个非常简单的 PHP 数据库前端管理面板;指定表的简单记录编辑器

javascript - anchor 上的动态ID不会在其他 anchor 上触发最后一个 anchor php js pdo

php - 我在这个 php/pdo 代码中有一个 HY093 错误,但我找不到它

PHPUnit 测试未使用带有 SQLite 数据库的 laravel 6.0 运行

php - fatal error : Call to a member function load() on a non-object (P4A application Framework)

php - 获取合并的两个表(不显示想要的结果)

php - jQuery 如何捕获 PHP 响应?