PHP命令行模式

2024-01-30 54

PHP命令行模式提供了一种在终端中执行PHP脚本的方式,它与其他SAPI(Server Application Programming Interface)模块有一些区别。在本文中,我们将介绍如何确定当前使用的是哪个SAPI,并讨论与其他SAPI模块的区别、选项、用法、I/O流、交互式shell、内置Web服务器和INI配置相关的内容。

一、判断SAPI

CLI SAPI 模块主要用作 PHP 的开发外壳应用。CLI SAPI 和其它 SAPI 模块相比有很多的不同之处。尽管 CLI 和 CGI 有很多共同的行为,但它们是不同的 SAPI。

CLI SAPI 模块会通过默认的 –enable-cli 参数设置启用, 也可以在运行 ./configure 时用参数 –disable-cli 来屏蔽。

CLI/CGI 二进制执行文件的文件名、位置和是否存在会根据 PHP 在系统上的安装而不同。在默认情况下,当运行 make 时,CGI 和 CLI 都会被编译并且分别放置在 PHP 源文件目录的 sapi/cgi/php-cgi 和 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 参数。

注意:由于 –enable-cli 和 –enable-cgi 同时默认有效,因此,不必再配置行中加上 –enable-cli 来使得 CLI 在 make install 过程中被拷贝到 {PREFIX}/bin/php。

在 Windows 发行包中,CLI 在主目录中的二进制文件名为 php.exe。CGI 版本的文件名为 php-cgi.exe。 如果 PHP 配置使用了 –enable-cli-win32,还会有一个额外的 php-win.exe 随包发布。 它相当于 CLI 版本,但是 php-win 不输出任何内容,便不提供控制台(不会弹出“DOS 窗口”)。

二、SAPI模块区别

以下为 CLI SAPI 和其它 SAPI 模块相比的显著区别:

1、与 CGI SAPI 不同,其输出没有任何头信息。

尽管 CGI SAPI 提供了取消 HTTP 头信息的方法,但在 CLI SAPI 中并不存在类似的方法以开启 HTTP 头信息的输出。

CLI 默认以安静模式开始,但为了保证兼容性,-q 和 –no-header 参数为了向后兼容仍然保留,使得可以使用旧的 CGI 脚本。

在运行时,不会把工作目录改为脚本的当前目录(可以使用 -C 和 –no-chdir 参数来兼容 CGI 模式)。出错时输出纯文本的错误信息(非 HTML 格式)。

2、CLI SAPI 强制覆盖了 php.ini 中的某些设置,因为这些设置在外壳环境下是没有意义的。

覆盖 php.ini 设置选项
设置选项 默认值 备注
html_errors false 无意义的 HTML 标记符会使得出错信息很凌乱,所以在外壳下阅读报错信息是十分困难的。因此将该选项的默认值改为 false
implicit_flush true 在命令行模式下,所有来自 print 和 echo 的输出将被立即写到输出端,而不作任何地缓冲操作。如果希望延缓或控制标准输出,仍然可以使用 output buffering 设置项。
max_execution_time 0(无限值) 鉴于在外壳环境下使用 PHP 的无穷的可能性,最大运行时间被设置为了无限值。为 web 开发的应用程序可能只需运行几秒钟时间,而外壳应用程序的运行时间可能会长的多。
register_argc_argv true

由于该设置为 true,将总是可以在CLI SAPI中访问到 argc(传送给应用程序参数的个数)和 argv(包含有实际参数的数组)。

在使用CLISAP时,PHP 变量 $argc 和 $argv 已被注册并且设定了对应的值。随时可以通过 $_SERVER 数组 来访问它们,例如:$_SERVER[‘argv’]

output_buffering false

虽然 php.ini 设置已经硬编码为 false, 输出缓冲控制函数仍然有效。

max_input_time false

PHP CLI 不支持 GET、POST、文件上传。

3、为了减轻外壳环境下的工作,我们为 I/O 流 定义了一系列常量。

4、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 模式,得到:

$ pwd
/tmp
$ php -q another_directory/test.php
/tmp

这使得在利用 PHP 编写外壳工具时获得了很大的便利。

三、选项

PHP 二进制文件可以随时通过执行带 -h 参数的 PHP 命令获取提供的命令行选项列表:

Usage: php [options] [-f] <file> [--] [args...]
php [options] -r <code> [--] [args...]
php [options] [-B <begin_code>] -R <code> [-E <end_code>] [--] [args...]
php [options] [-B <begin_code>] -F <file> [-E <end_code>] [--] [args...]
php [options] -- [args...]
php [options] -a
-a Run interactively
-c <path>|<file> Look for php.ini file in this directory
-n No php.ini file will be used
-d foo[=bar] Define INI entry foo with value 'bar'
-e Generate extended information for debugger/profiler
-f <file> Parse and execute <file>.
-h This help
-i PHP information
-l Syntax check only (lint)
-m Show compiled in modules
-r <code> Run PHP <code> without using script tags <?..?>
-B <begin_code> Run PHP <begin_code> before processing input lines
-R <code> Run PHP <code> for every input line
-F <file> Parse and execute <file> for every input line
-E <end_code> Run PHP <end_code> after processing all input lines
-H Hide any passed arguments from external tools.
-S <addr>:<port> Run with built-in web server.
-t <docroot> Specify document root <docroot> for built-in web server.
-s Output HTML syntax highlighted source.
-v Version number
-w Output source with stripped comments and whitespace.
-z <file> Load Zend extension <file>.
args... Arguments passed to script. Use -- args when first argument
starts with - or script is read from stdin
--ini Show configuration file names
--rf <name> Show information about function <name>.
--rc <name> Show information about class <name>.
--re <name> Show information about extension <name>.
--rz <name> Show information about Zend extension <name>.
--ri <name> Show configuration for extension <name>.

命令行选项:

命令行选项
选项 长选项 说明
-a –interactive

运行交互式 PHP。

-b –bindpath

外部 FASTCGI 服务器模式绑定路径(仅 CGI可用)。

-C –no-chdir

不改变脚本的目录(仅 CGI 可用)。

-q –no-header

安静模式。禁止输出 HTTP 头(仅CGI可用)。

-T –timing

测量脚本重复 count 次的执行时间(仅 CGI可用)。

-c –php-ini

在指定目录查找 php.ini 或者自定义 INI 文件(名称可以不是 php.ini),例如:

$ php -c /custom/directory/ my_script.php

$ php -c /custom/directory/custom-file.ini my_script.php

如果未指定此选项,php.ini 将在默认位置搜索。

-n –no-php-ini

完全忽略 php.ini

-d –define

允许设置 php.ini 中配置指令的值。语法是:

 -d configuration_directive[=value]
# 忽略值部分,将会设置配置指令为 "1"
$ php -d max_execution_time
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(1) "1"

# 传递空值,将会设置配置指令为 ""
php -d max_execution_time=
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(0) ""

# 配置指令将会设置为 '=' 字符之后传递的任何值
$  php -d max_execution_time=20
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(2) "20"
$  php
        -d max_execution_time=doesntmakesense
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(15) "doesntmakesense"
-e –profile-info

激活扩展信息模式,用于调试/分析。

-f –file

解析并执行指定文件。 -f 可选且可以忽略 —— 只需提供需要执行的文件名就足够。

-h and -? –help and –usage 输出命令行选项列表并描述了这些选项的作用。
-i –info 调用 phpinfo() 并输出结果。如果 PHP 不能正常工作,建议使用命令 php -i 查看在信息表输出之前或者中间某个位置是否有错误消息。注意当使用 CGI 模式时会输出HTML, 这会非常大。
-l –syntax-check

提供了仅对指定 PHP 代码进行语法检查的便捷方法。 成功时将会在标准输出中写入 No syntax errors detected in <filename> 并且 shell 返回码为 0。失败时除了将会在标准输出中写入内部解析错误消息之外,还会写入 Errors parsing <filename>,并且 shell 返回码为 -1

此选项不能发现像是函数未定义之类的核心错误(fatal errors)。可以使用 -f 测试核心错误(fatal errors)。

注意:

此选项不能和 -r 一起使用。

-m –modules

示例 #1 打印内置(且已加载的) PHP 和 Zend 模块

$ php -m
[PHP Modules]
xml
tokenizer
standard
session
posix
pcre
overload
mysql
mbstring
ctype

[Zend Modules]
-r –run

允许在命令行内直接执行单行 PHP 代码。 不需要加上 PHP 开始和结束标识符(<?php 和 ?>),否则将会造成语法错误。

注意:

使用这种形式的 PHP 时,应注意避免和 shell 环境进行的命令行参数替换相冲突。

示例 #2 当使用双引号时会造成语法错误

$ php -r "$foo = get_defined_constants();"
PHP Parse error:  syntax error, unexpected '=' in Command line code on line 1

Parse error: syntax error, unexpected '=' in Command line code on line 1

这里的问题是在使用双引号 " 时 sh/bash 会执行变量替换。 由于 $foo 变量没有被定义,因此它将替换为空字符, 从而导致传递给 PHP 执行的代码实际上会变成:

$ php -r " = get_defined_constants();"

正确的方式是使用单引号 ' 。使用单引号时 sh/bash 不会进行变量替换。

示例 #3 使用单引号防止 shell 变量替换

$ php -r '$foo = get_defined_constants(); var_dump($foo);'
array(370) {
  ["E_ERROR"]=>
  int(1)
  ["E_WARNING"]=>
  int(2)
  ["E_PARSE"]=>
  int(4)
  ["E_NOTICE"]=>
  int(8)
  ["E_CORE_ERROR"]=>
  [...]

如果使用的 shell 不是 sh/bash,可能会碰到更多的问题 —— 如果有的话,请向 » https://github.com/php/php-src/issues 报告 bug。试图在命令行中使用( shell/PHP )变量或者使用反斜杠转义时需要格外小心,因为很容易遇到问题。勿谓言之不预!

注意:

可以在CLISAPI<中使用 -r,但不能在 CGISAPI中使用。

注意:

此选项仅适用于非常基本的代码,因此在此模式下会忽略某些配置指令(如 auto_prepend_file 和 auto_append_file)。

-B –process-begin

处理 stdin 之前需要执行的 PHP 代码。

-R –process-code

对每个输入行都执行的 PHP 代码。

此模式下有两个特殊变量: $argn 和 $argi。 $argn 将包含 PHP 正在处理的行, $argi 将包含正在处理的行号。

-F –process-file

对每个输入行都执行的 PHP 文件。

-E –process-end

在处理完输入后执行的 PHP 代码。

示例 #4 使用 -B 、 -R 、 -E 选项统计项目总行数。

$ find my_proj | php -B '$l=0;' -R '$l += count(@file($argn));' -E 'echo "Total Lines: $l\n";'
Total Lines: 37328
-S –server

启动 内置 web 服务器.

-t –docroot 为内置 web 服务器指定文档根目录。
-s –syntax-highlight 和 –syntax-highlighting

为源代码添加语法高亮显示。

此选项将使用内部机制解析文件并将生成的 HTML 高亮版本写入到标准输出。 注意它所做的只是生成一块 <code> [...] </code> HTML 标记,没有 HTML header。

注意:

此选项不能和 -r 一起使用。

-v –version

示例 #5 使用 -v 获取 SAPI 的名称以及 PHP 和 Zend 的版本号

$ php -v
PHP 5.3.1 (cli) (built: Dec 11 2009 19:55:07)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies
-w –strip

显示忽略注释和空格后的源代码。

注意:

此选项不能和 -r 一起使用。

-z –zend-extension

加载 Zend 扩展。如果仅指定了文件名,PHP 将尝试从当前系统默认函数库中尝试加载此扩展 (例如在 Linux 上通常是 /etc/ld.so.conf)。 传递绝对路径的文件名将不会使用系统库搜索路径。如果用相对路径指定的文件名,则 PHP 仅试图在当前目录的相对目录加载扩展库。

–ini

展示配置文件名和扫描目录。

示例 #6 --ini 示例

$ php --ini
Configuration File (php.ini) Path: /usr/dev/php/5.2/lib
Loaded Configuration File:         /usr/dev/php/5.2/lib/php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)
–rf –rfunction

展示指定函数或者类方法的有关信息(例如参数名称和数量)。

如果 PHP 在编译时启用 Reflection 支持,该选项才可以使用。

示例 #7 基础 --rf 用法

$ php --rf var_dump
Function [ <internal> public function var_dump ] {

  - Parameters [2] {
    Parameter #0 [ <required> $var ]
    Parameter #1 [ <optional> $... ]
  }
}
–rc –rclass

展示指定类的有关信息(常量、属性和方法的列表)。

如果 PHP 在编译时启用 Reflection 支持,该选项才可以使用。

示例 #8 --rc 示例

$ php --rc Directory
Class [ <internal:standard> class Directory ] {

  - Constants [0] {
  }

  - Static properties [0] {
  }

  - Static methods [0] {
  }

  - Properties [0] {
  }

  - Methods [3] {
    Method [ <internal> public method close ] {
    }

    Method [ <internal> public method rewind ] {
    }

    Method [ <internal> public method read ] {
    }
  }
}
–re –rextension

展示指定扩展的有关信息(php.ini 选项、定义函数、常量和类的列表)。

如果 PHP 在编译时启用 Reflection 支持,该选项才可以使用。

示例 #9 --re 示例

$ php --re json
Extension [ <persistent> extension #19 json version 1.2.1 ] {

  - Functions {
    Function [ <internal> function json_encode ] {
    }
    Function [ <internal> function json_decode ] {
    }
  }
}
–rz –rzendextension

展示指定 Zend 扩展的配置信息(也可以通过 phpinfo()返回相同信息)。

–ri –rextinfo

展示指定扩展的配置信息(也可以通过 phpinfo()返回相同信息)。 使用 “main” 作为扩展名可以获取到核心配置信息。

示例 #10 --ri 示例

$ php --ri date

date

date/time support => enabled
"Olson" Timezone Database Version => 2009.20
Timezone Database => internal
Default timezone => Europe/Oslo

Directive => Local Value => Master Value
date.timezone => Europe/Oslo => Europe/Oslo
date.default_latitude => 59.930972 => 59.930972
date.default_longitude => 10.776699 => 10.776699
date.sunset_zenith => 90.583333 => 90.583333
date.sunrise_zenith => 90.583333 => 90.583333

四、用法

参考《PHP命令行模式用法》。

五、I/O流

CLI SAPI 为 I/O 流定义了一些常量,以使命令行变量编程更容易一些。

CLI 特定常量
常量 描述
STDIN

已经打开的 stdin 流。使得无需再用以下方式打开:

<?php
$stdin = fopen('php://stdin', 'r');
?>

如果想从 stdin 中读取一行内容,可以使用如下方式:

<?php
$line = trim(fgets(STDIN)); // 从 STDIN 读取一行
fscanf(STDIN, "%d\n", $number); // 从 STDIN 读取数字
?>
STDOUT

已经打开的 stdout 流。使得无需再用以下方式打开:

<?php
$stdout = fopen('php://stdout', 'w');
?>
STDERR

已经打开的 stderr 流。使得无需再用以下方式打开:

<?php
$stderr = fopen('php://stderr', 'w');
?>

综上所述,则无需打开 stderr 流,只需使用常量代替流资源:

php -r 'fwrite(STDERR, "stderr\n");'

无须显式关闭这些流,因为它们会在脚本结束时由 PHP 自动关闭。

六、交互式shell

参考《PHP交互式shell》。

七、内置Web Server

参考《PHP内置Web Server》。

八、INI配置

CLI SAPI 配置选项:

CLI SAPI 配置选项
名字 默认 可修改范围 更新日志
cli_server.color “0” INI_ALL

这是配置指令的简短说明。

cli_server.color boolean

控制内置Web Server的终端输出有无颜色。

  • 广告合作

  • QQ群号:707632017

温馨提示:
1、本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。邮箱:2942802716#qq.com(#改为@)。 2、本站原创内容未经允许不得转裁,转载请注明出处“站长百科”和原文地址。