从版本 4.3.0 开始,PHP 提供了一种新类型的 CLI SAPI(Server Application Programming Interface,服务端应用编程端口)支持,名为 CLI,意为 Command Line Interface,即命令行接口。顾名思义,该 CLI SAPI 模块主要用作 PHP 的开发外壳应用。CLI SAPI 和其它 CLI SAPI 模块相比有很多的不同之处,我们将在本章中详细阐述。值得一提的是,CLI 和 CGI 是不同的 SAPI,尽管它们之间有很多共同的行为。
CLI SAPI 最先是随 PHP 4.2.0 版本发布的,但仍旧只是一个实验性的版本,并需要在运行 ./configure 时加上 --enable-cli 参数。从 PHP 4.3.0 版本开始,CLI SAPI 成为了正式模块,--enable-cli 参数会被默认得设置为 on,也可以用参数 --disable-cli 来屏蔽。
从 PHP 4.3.0开始,CLI/CGI 二进制执行文件的文件名、位置和是否存在会根据 PHP 在系统上的安装而不同。在默认情况下,当运行 make 时,CGI 和 CLI 都会被编译并且分别放置在 PHP 源文件目录的 sapi/cgi/php 和 sapi/cli/php 下。可以注意到两个文件都被命名为了 php。在 make install 的过程中会发生什么取决于配置行。如果在配置的时候选择了一个 SAPI 模块,如 apxs,或者使用了 --disable-cgi 参数,则在 make install 的过程中,CLI 将被拷贝到 {PREFIX}/bin/php,除非 CGI 已经被放置在了那个位置。因此,例如,如果在配置行中有 --with--apxs ,则在 make install 的过程中,CLI 将被拷贝到 {PREFIX}/bin/php。如果希望撤销 CGI 执行文件的安装,请在 make install 之后运行 make install-cli。或者,也可以在配置行中加上 --disable-cgi 参数。
Note:
由于 --enable-cli 和 --enable-cgi 同时默认有效,因此,不必再配置行中加上 --enable-cli 来使得 CLI 在 make install 过程中被拷贝到 {PREFIX}/bin/php。
在 PHP 4.2.0 到 PHP 4.2.3 之间的 Windows 发行包中,CLI 的文件名为 php-cli.exe,相同文件夹下的 php.exe 为 CGI。从 PHP 4.3.0 版本开始,Windows 的发行包中 CLI 的执行文件为 php.exe,被放置在一个单独的名为 cli 的文件夹下,即 cli/php.exe。在 PHP 5 中,CLI 存在于主文件夹中,名为 php.exe,而 CGI 版本名为 php-cgi.exe。
从 PHP 5 起,一个名为 php-win.exe 的新文件随包发布。它相当于 CLI 版本,但是 php-win 不输出任何内容,便不提供控制台(不会弹出“DOS 窗口”)。这种方式类似于 php-gtk。需要使用 --enable-cli-win32 选项来配置它。
Note: 如何得知自己使用的是哪个 SAPI?
在命令行下,运行 php -v 便能得知该 php 是 CGI 还是 CLI。请参考函数 php_sapi_name() 以及常量
PHP_SAPI
。
Note:
在 PHP 4.3.2 中加入了 Unix 的 man 页面。可以在命令行中键入 man php 来查看。
以下为 CLI SAPI 和其它 CLI SAPI 模块相比的显著区别:
与 CGI SAPI 不同,其输出没有任何头信息。
尽管 CGI SAPI 提供了取消 HTTP 头信息的方法,但在 CLI SAPI 中并不存在类似的方法以开启 HTTP 头信息的输出。
CLI 默认以安静模式开始,但为了保证兼容性,-q 和 --no-header 参数为了向后兼容仍然保留,使得可以使用旧的 CGI 脚本。
在运行时,不会把工作目录改为脚本的当前目录(可以使用 -C 和 --no-chdir 参数来兼容 CGI 模式)。
出错时输出纯文本的错误信息(非 HTML 格式)。
CLI SAPI 强制覆盖了 php.ini 中的某些设置,因为这些设置在外壳环境下是没有意义的。
设置选项 | CLI SAPI 默认值 | 备注 |
---|---|---|
html_errors | FALSE |
无意义的 HTML
标记符会使得出错信息很凌乱,所以在外壳下阅读报错信息是十分困难的。因此将该选项的默认值改为 FALSE 。
|
implicit_flush | TRUE |
在命令行模式下,所有来自 print 和 echo 的输出将被立即写到输出端,而不作任何地缓冲操作。如果希望延缓或控制标准输出,仍然可以使用 output buffering 设置项。 |
max_execution_time | 0(无限值) | 鉴于在外壳环境下使用 PHP 的无穷的可能性,最大运行时间被设置为了无限值。为 web 开发的应用程序可能只需运行几秒钟时间,而外壳应用程序的运行时间可能会长的多。 |
register_argc_argv | TRUE |
由于该设置为 对于 PHP 4.3.0,在使用 CLI SAPI 时,PHP 变量 $argc 和 $argv 已被注册并且设定了对应的值。而在这之前的版本,这两个变量在 CGI 或者 模块 版本中的建立依赖于将 PHP 的设置选项 register_globals 设为 on。除了版本和 register_globals 设定以外,可以随时通过调用 $_SERVER 或者 $HTTP_SERVER_VARS 来访问它们。例如:$_SERVER['argv'] |
Note:
这些设置无法在设置文件 php.ini 或任何指定的其它文件中被初始化为其它值。这些默认值被限制在所有其它的设置文件被解析后改变。不过,它们的值可以在程序运行的过程中被改变(尽管对于该运行过程来说,这些设置项是没有意义的)。
为了减轻外壳环境下的工作,我们定义了如下常量:
常量名称 | 描 述 |
---|---|
STDIN |
一个已打开的指向 stdin 的流。可以用如下方法来调用:
<?php
<?php |
STDOUT |
一个已打开的指向 stdout 的流。可以用如下方式来调用:
<?php |
STDERR |
一个已打开的指向 stderr 的流。可以用如下方式来调用:
<?php |
有了以上常量,就无需自己建立指向诸如 stderr 的流,只需简单的使用这些常量来代替流指向:
php -r 'fwrite(STDERR, "stderr\n");'
CLI SAPI 不会将当前目录改为已运行的脚本所在的目录。
以下范例显示了本模块与 CGI SAPI 模块之间的不同:
<?php
// 名为 test.php 的简单测试程序
echo getcwd(), "\n";
?>
在使用 CGI 版本时,其输出为
$ pwd /tmp $ php-cgi -f another_directory/test.php /tmp/another_directory
明显可以看到 PHP 将当前目录改成了刚刚运行过的脚本所在的目录。
使用 CLI SAPI 模式,得到: