`

PHP 的命令行模式

    博客分类:
  • php
阅读更多
PHP 的命令行模式

从版本 4.3.0 开始,PHP 提供了一种新类型的 SAPI(Server Application Programming Interface,服务端应用编程端口)支持,名为 CLI,意为 Command Line Interface,即命令行接口。顾名思义,该 SAPI 模块主要用作 PHP 的开发外壳应用。CLI SAPI 和其它 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 参数。

    注: 由于 --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。

    这是哪个 SAPI?: 在命令外壳下,运行 php -v 便能得知该 php 是 CGI 还是 CLI。请参考函数 php_sapi_name() 以及常量 PHP_SAPI。

    注: 在 PHP 4.3.2 中加入了 UNIX 的 man 页面。可以在你的命令外壳下键入 man php 来查看。

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

    *

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

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

      CLI 默认以安静模式开始,但为了保证兼容性, -q 参数使得您可以使用旧的 CGI 脚本。

      在运行时,不会把工作目录改为脚本的当前目录。(您可以使用 -C 参数来兼容 CGI 模式)。

      出错时输出纯文本的错误信息(非 HTML 格式)。
    *

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

      表格 23-1. 被更改的 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

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

      对于 PHP 4.3.0,在使用 CLI SAPI 时,PHP 变量 $argc 和 $argv 已被注册并且设定了对应的值。而在这之前的版本,这两个变量在 CGI 或者 模块 版本中的建立依赖于将 PHP 的设置选项 register_globals 设为 on。除了版本和 register_globals 设定以外,您可以随时通过调用 $_SERVER 或者 $HTTP_SERVER_VARS来访问它们。例如:$_SERVER['argv']

          注: 这些设置无法在设置文件 php.ini 或任何指定的其它文件中被初始化为其它值。这些默认值被限制在所有其它的设置文件被解析后改变。不过,它们的值可以在程序运行的过程中被改变(尽管对于该运行过程来说,这些设置项是没有意义的)。

    *

      为了减轻外壳环境下的工作,我们定义了如下常量:

      表格 23-2. CLI 专用常量
      常量名称 描 述
      STDIN 一个已打开的指向 stdin 的流。您可以用如下方法来调用:
      $stdin = fopen('php://stdin', 'r');
      STDOUT 一个已打开的指向 stdout 的流。您可以用如下方式来调用:
      $stdout = fopen('php://stdout', 'w');
      STDERR 一个已打开的指向 stderr 的流。您可以用如下方式来调用:
      $stderr = fopen('php://stderr', 'w');

      有了以上常量,您就无需自己建立指向诸如 stderr 的流,只需简单的使用这些常量来代替流指向:
      php -r 'fwrite(STDERR, "stderr\n");'
      您无需自己来关闭这些流,PHP 会自动完成这些操作。
    *

      CLI SAPI 不会将当前目录改为已运行的脚本所在的目录。

      以下范例显示了本模块与 CGI SAPI 模块之间的不同:
      <?php
          /* Our simple test application named 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 编写外壳工具时获得了很大的便利。

          注: 您可以在命令行运行时给 CGI SAPI 加上 -C 参数,使其支持 CLI SAPI 的功能。

以下是 PHP 二进制文件(即 php.exe 程序)提供的命令行模式的选项参数,您随时可以通过 PHP -h 命令来查询这些参数。

Usage: php [options] [-f] <file> [args...]
       php [options] -r <code> [args...]
       php [options] [-- args...]
  -s               Display colour syntax highlighted source.
  -w               Display source with stripped comments and whitespace.
  -f <file>        Parse <file>.
  -v               Version number
  -c <path>|<file> Look for php.ini file in this directory
  -a               Run interactively
  -d foo[=bar]     Define INI entry foo with value 'bar'
  -e               Generate extended information for debugger/profiler
  -z <file>        Load Zend extension <file>.
  -l               Syntax check only (lint)
  -m               Show compiled in modules
  -i               PHP information
  -r <code>        Run PHP <code> without using script tags <?..?>
  -h               This help

  args...          Arguments passed to script. Use -- args when first argument
                   starts with - or script is read from stdin

CLI SAPI 模块有以下三种不同的方法来获取您要运行的 PHP 代码:

   1.

      让 PHP 运行指定文件。

      php my_script.php

      php -f my_script.php

      以上两种方法(使用或不使用 -f 参数)都能够运行给定的 my_script.php 文件。您可以选择任何文件来运行,您指定的 PHP 脚本并非必须要以 .php 为扩展名,它们可以有任意的文件名和扩展名。
   2.

      在命令行直接运行 PHP 代码。

      php -r 'print_r(get_defined_constants());'

      在使用这种方法时,请您注意外壳变量的替代及引号的使用。

          注: 请仔细阅读以上范例,在运行代码时没有开始和结束的标记符!加上 -r 参数后,这些标记符是不需要的,加上它们会导致语法错误。

   3.

      通过标准输入(stdin)提供需要运行的 PHP 代码。

      以上用法给我们提供了非常强大的功能,使得我们可以如下范例所示,动态地生成 PHP 代码并通过命令行运行这些代码:

      $ some_application | some_filter | php | sort -u >final_output.txt

以上三种运行代码的方法不能同时使用。

和所有的外壳应用程序一样,PHP 的二进制文件(php.exe 文件)及其运行的 PHP 脚本能够接受一系列的参数。PHP 没有限制传送给脚本程序的参数的个数(外壳程序对命令行的字符数有限制,但您通常都不会超过该限制)。传递给您脚本的参数可在全局变量 $argv 中获取。该数组中下标为零的成员为脚本的名称(当 PHP 代码来自标准输入获直接用 -r 参数以命令行方式运行时,该名称为“-”)。另外,全局变量 $argc 存有 $argv 数组中成员变量的个数(而非传送给脚本程序的参数的个数)。

只要您传送给您脚本的参数不是以 - 符号开头,您就无需过多的注意什么。向您的脚本传送以 - 开头的参数会导致错误,因为 PHP 会认为应该由它自身来处理这些参数。您可以用参数列表分隔符 -- 来解决这个问题。在 PHP 解析完参数后,该符号后所有的参数将会被原样传送给您的脚本程序。

# 以下命令将不会运行 PHP 代码,而只显示 PHP 命令行模式的使用说明:
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]

# 以下命令将会把“-h”参数传送给脚本程序,PHP 不会显示命令行模式的使用说明:
$ php -r 'var_dump($argv);' -- -h
array(2) {
  [0]=>
  string(1) "-"
  [1]=>
  string(2) "-h"
}

除此之外,我们还有另一个方法将 PHP 用于外壳脚本。您可以在写一个脚本,并在第一行以 #!/usr/bin/php 开头,在其后加上以 PHP 开始和结尾标记符包含的正常的 PHP 代码,然后为该文件设置正确的运行属性。该方法可以使得该文件能够像外壳脚本或 PERL 脚本一样被直接执行。
#!/usr/bin/php
<?php
    var_dump($argv);
?>

假设改文件名为 test 并被放置在当前目录下,我们可以做如下操作:

$ chmod 755 test
$ ./test -h -- foo
array(4) {
  [0]=>
  string(6) "./test"
  [1]=>
  string(2) "-h"
  [2]=>
  string(2) "--"
  [3]=>
  string(3) "foo"
}

正如您所看到的,在您向该脚本传送以 - 开头的参数时,脚本仍然能够正常运行。

表格 23-3. 命令行选项
选项名称 描 述
-s

显示有语法高亮色彩的源文件。

该参数使用内建机制来解析文件并为其生成一个 HTML 高亮版本并将结果写到标准输出。请注意该过程所做的只是生成了一个 <code> [...] </code> 的 HTML 标记符块,并不包含任何的 HTML 头。

    注: 该选项不能和 -r 参数同时使用。

-w

显示除去了注释和空格的源代码。

    注: 该选项不能和 -r 参数同时使用。

-f

解析并运行给定的文件名。该参数为可选参数且可以不加,仅指明需要运行的文件名即可。
-v

将 PHP、PHP SAPI 及 Zend 的版本信息写入的标准输出。例如:

$ php -v
PHP 4.3.0-dev (cli), Copyright (c) 1997-2002 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2002 Zend Technologies

-c

用该参数,您可以指定一个放置 php.ini 文件的目录,或者直接指定一个自定义的 INI 文件,其文件名可以不是 php.ini。例如:

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

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

-a

交互地运行 PHP。
-d

用该参数可以自行设置 php.ini 文件中设置变量的值,其语法为:

-d configuration_directive[=value]

范例:

# Ommiting the value part will set the given configuration directive to "1"
$ php -d max_execution_time
       -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(1) "1"

# Passing an empty value part will set the configuration directive to ""
php -d max_execution_time=
       -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(0) ""

# The configuration directive will be set to anything passed after the '=' character
$  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

为调试器等生成扩展信息。
-z

加载 Zend 扩展库。如果仅给定一个文件名,PHP 将试图从您系统扩展库的默认路径(在 Linux 系统下,该路径通常由 /etc/ld.so.conf 指定)加载该扩展库。如果您用一个绝对路径指定文件名,则系统的扩展库默认路径将不会被使用。如果用相对路径指定的文件名,PHP 则仅试图加载相对于当前目录的扩展库。
-l

该参数提供了对指定 PHP 代码进行语法检查的方便的方法。如果成功,则向标准输出写入 No syntax errors detected in <filename> 字符串,并且外壳返回值为 0。如果失败,则 Errors parsing <filename> 以及内部解析器错误信息会一起被写入到标准输出,同时外壳返回值将别设置为 255。

该参数将无法检查致命错误(如未定义函数),如果您希望检测之名错误,请使用 -f 参数。

    注: 该参数不能和 -r 一同使用。

-m

使用该参数,PHP 将打印出内置以及已加载的 PHP 及 Zend 模块:

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

[Zend Modules]

-i 该命令行参数会调用 phpinfo() 函数,并打印出结果。如果 PHP 没有正常工作,我们建议您执行 php -i 命令来查看在信息表格之前或者对应的地方是否有任何错误信息输出。请注意输出的内容为 HTML 格式,因此输出的信息篇幅较大。
-r

使用该参数可以在命令行运行 PHP 代码。您无需加上 PHP 的起始和结束标识符(<?php 和 ?>),否则将会导致语法解析错误。

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

    显示语法解析错误的范例

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

    这里的问题在于即时使用了双引号 ",sh/bash 仍然实行了参数替换。由于 $foo 没有被定义,被替换后它所在的位置变成了空字符,因此在运行时,实际被 PHP 读取的代码为:

    $ php -r " = get_defined_constants();"

    正确的方法是使用单引号 '。在用单引号引用的字符串中,变量不会被 sh/bash 还原成其原值。

    $ 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"]=>
      [...]

    如果您使用的外壳不是 sh/bash,您可能会碰到其它的问题。请报告您碰到的 bug,或者发邮件到 phpdoc@lists.php.net。

    当您试图将外壳的环境变量引入到马或者用反斜线来转义字符时也可能碰到各种各样的问题,请您在使用时注意!

    注: -r 在 CLI SAPI 中有效,在 CGI SAPI 中无效。

-h 使用该参数,您可以得到完整的命令行参数的列表及这些参数作用的简单描述。

PHP 的命令行模式能使得 PHP 脚本能完全独立于 WEB 服务器单独运行。如果您使用 Unix 系统,您需要在您的 PHP 脚本的最前面加上一行特殊的代码,使得它能够被执行,这样系统就能知道用什么样的程序要运行该脚本。在 Windows 平台下您可以将 php.exe 和 .php 文件的双击属性相关联,您也可以编写一个批处理文件来用 PHP 执行脚本。为 Unix 系统增加的第一行代码不会影响该脚本在 Windows 下的运行,因此您也可以用该方法编写跨平台的脚本程序。以下是一个简单的PHP 命令行程序的范例。

例子 23-1. 试图以命令行方式运行的 PHP 脚本(script.php)
#!/usr/bin/php
<?php

if ($argc != 2 || in_array($argv[1], array('--help', '-help', '-h', '-?'))) {
?>

This is a command line PHP script with one option.

  Usage:
  <?php echo $argv[0]; ?> <option>

  <option> can be some word you would like
  to print out. With the --help, -help, -h,
  or -? options, you can get this help.

<?php
} else {
    echo $argv[1];
}
?>

在以上脚本中,我们用第一行特殊的代码来指明该文件应该由 PHP 来执行。我们在这里使用 CLI 的版本,因此不会有 HTTP 头信息输出。在您用 PHP 编写命令行应用程序时,您可以使用两个参数:$argc 和 $argv。前面一个的值是比参数个数大 1 的整数(运行的脚本本身的名称也被当作一个参数)。第二个时包含有参数的数组,其第一个元素为脚本的名称,下标为数字 0($argv[0])。

在以上程序中我们检查了参数的个数是大于 1 个还是小于 1 个。即时参数是 --help、-help、-h 或 -?,我们仍然打印出帮助信息,并同时动态输出脚本的名称。如果还收到了其它参数,我们也把它们显示出来。

如果您希望在 Unix 下运行以上脚本,您需要使得它成为可执行脚本,然后简单的运行 script.php echothis 或 script.php -h。在 Windows 下,您可以为此编写一个批处理文件:

例子 23-2. 运行 PHP 命令行脚本的批处理文件(script.bat)

@c:\php\cli\php.exe script.php %1 %2 %3 %4

假设您将上述程序命名为 script.php,且您的 CLI php.exe 文件放置在 c:\php\cli\php.exe,该批处理文件会帮助您将附加的参数传给脚本程序: script.bat echothis 或 script.bat -h。
分享到:
评论

相关推荐

    PHP 命令行模式开发框架mix-master.zip

    当我们谈论"PHP命令行模式开发框架"时,我们是指利用PHP不仅进行网页应用的开发,还可以通过命令行接口(CLI)执行任务。这种模式允许开发者创建独立于Web服务器的应用程序,如后台任务、自动化脚本或者工具。 "mix...

    利用PHP命令行模式采集股票趋势信息

    标题《利用PHP命令行模式采集股票趋势信息》指出了本文的主题是介绍如何使用PHP语言在命令行环境下编写程序以采集股票市场的趋势信息。描述部分提到该程序能够采集同花顺股票的趋势数据,重点在于采集功能的实现。...

    php cli模式学习(PHP命令行模式)

    php_cli模式简介 php-cli是php Command Line Interface的简称,如同它名字的意思,就是php在命令行运行的接口,区别于在Web服务器上运行的php环境(php-cgi, isapi等) 也就是说,php不单可以写前台网页,它还可以...

    MixPHP 命令行模式开发框架 v3.0.17.zip

    MixPHP 是一个轻量级的、高性能的 PHP 开发框架,尤其适合命令行模式下的应用开发。v3.0.17 版本是该框架的一个稳定版本,它提供了许多改进和新特性,以帮助开发者更高效地构建 CLI(Command Line Interface)应用...

    php命令行(cli)模式下报require 加载路径错误的解决方法

    【PHP命令行模式(CLI)】 PHP命令行模式,也称为CLI模式,是一种通过命令行接口执行PHP脚本的方式,常用于批处理任务、服务器维护、自动化脚本等场景。在CLI模式下,PHP解释器可以直接运行PHP文件,而不需要通过Web...

    php命令行写shell实例详解

    PHP命令行模式还支持 `-z` 参数,用来加载Zend扩展。对于想要深入了解PHP扩展信息的开发者,可以使用 `--rf`, `--rc`, `--re`, `--rz`, `--ri` 参数来查看函数、类、扩展、Zend扩展以及扩展配置的相关信息。 例如,...

    PHP的命令行命令使用指南

    PHP命令行模式最大的优点之一是它可以用来执行计划任务。无需通过Web服务器,可以直接使用命令行工具来安排和执行脚本。这对于自动备份、定时清理文件等任务非常有用。 例如,可以创建一个定时任务,在特定时间执行...

    Linux平台php命令行程序处理管道数据的方法

    PHP命令行模式下,脚本可以通过全局变量$argc和$argv来获取传递给脚本的命令行参数。$argc表示传递的参数数量,$argv是一个数组,包含了传递给脚本的各个参数。 5. 使用PHP实现标准Unix/Linux命令功能 通过上述技巧...

    ThinkPHP3.1.2 使用cli命令行模式运行的方法

    为了更好地处理URL参数,我们可以编写额外的代码,以确保在命令行模式下也能正确地传递参数。例如,如果命令行参数超过三个,可以通过正则表达式将这些参数转换为GET参数: ```php if ($argc &gt; 3) { preg_replace...

    PHP 命令行参数详解及应用

    在PHP的命令行模式下,PHP的可执行程序提供了丰富的命令行参数,使得开发者可以在非Web环境下使用PHP的功能。这些参数包括: 1. `-q`:安静模式。不输出HTTP头信息,这对于将PHP脚本作为后台或批处理任务运行非常...

    命令行执行php脚本中的$argv和$argc配置方法

    这两个变量的使用无需额外设置,它们是PHP命令行模式(CLI)下的默认功能。这对于那些不需要HTTP环境,而需要直接通过命令行接收和处理数据的脚本来说非常有用。例如,用于定期执行的任务调度(cron jobs)、数据库...

    PHP内核探索之解释器的执行过程

    cli(Command Line Interface)即PHP的命令行模式,现在...CLI是php命令行模式,此SAPI是默认安装的,在服务器端安装过PHP后,生成以一个可执行文件,可以在shell中调用PHP命令来执行。 复制代码 代码如下: PHP -f XX.p

    Fink一个PHP编写的命令行工具用于检查网站是否有错误的页面或链接

    "Fink" 是一款基于 PHP 的命令行工具,专为网站管理员和开发者设计,用于检测和查找网站中存在的错误页面或损坏的链接。这款工具利用了 PHP 的强大功能,结合了快速并发的 HTTP 请求技术,能够高效地扫描网站的各个...

    GetOptionKit一个面向对象的PHP命令行参数解析器

    这个库为开发者提供了一种优雅的方式来处理命令行输入,使得构建具有复杂选项和...通过查阅官方文档或源码中的示例,你可以快速掌握其用法,并将其应用到你的PHP命令行项目中,提升命令行工具的用户体验和开发效率。

    MixCLI让PHP像Golang一样开发命令行程序单执行文件

    MixCLI就是为了让PHP具备这种能力,使得PHP命令行工具的开发和分发变得更加简单。 【描述解析】 描述部分再次强调了MixCLI的主要功能,即使PHP开发者能够以与Golang类似的方式构建命令行程序,生成单执行文件。这...

    基于命令行执行带参数的php脚本并取得参数的方法

    同时,需要注意的是,在命令行模式下,某些PHP扩展可能未启用,或者环境变量可能与Web服务器环境不同,所以在开发过程中需要考虑这些差异。 总结起来,掌握在命令行下执行带参数的PHP脚本是一项实用技能,它可以...

Global site tag (gtag.js) - Google Analytics