CLI —— PHP的命令行模式

php本身就是一种脚本语言,不过我们一般都是通过apache来执行php,当然php也是可以通过命令行来执行的,和perl等语言类似。

从版本 4.3.0 开始,PHP 提供了一种新类型的 SAPI(Server Application Programming Interface,服务端应用编程端口)支持,名为 CLI,意为 Command Line Interface,即命令行接口。顾名思义,该 SAPI 模块主要用作 PHP 的开发外壳应用。CLI SAPI 和其它 SAPI 模块相比有很多的不同之处,我们将在本章中详细阐述。值得一提的是,CLI 和 CGI 是不同的 SAPI,尽管它们之间有很多共同的行为。

在 PHP 5 中,CLI 存在于主文件夹中,名为 php.exe,而 CGI 版本名为 php-cgi.exe。 从 PHP 5 起,一个名为 php-win.exe 的新文件随包发布。它相当于 CLI 版本,但是 php-win 不输出任何内容,便不提供控制台(不会弹出“DOS 窗口”)。这种方式类似于 php-gtk。需要使用 --enable-cli-win32 选项来配置它。

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

  • CGI SAPI 不同,其输出没有任何头信息。尽管 CGI SAPI 提供了取消 HTTP 头信息的方法,但在 CLI SAPI 中并不存在类似的方法以开启 HTTP 头信息的输出。
  • CLI 默认以安静模式开始,但为了保证兼容性,-q--no-header 参数为了向后兼容仍然保留,使得可以使用旧的 CGI 脚本。
  • 在运行时,不会把工作目录改为脚本的当前目录(可以使用 -C--no-chdir 参数来兼容 CGI 模式)。
  • 出错时输出纯文本的错误信息(非 HTML 格式)。

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

覆盖 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']

Note:

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

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

CLI 专用常量
常量名称 描 述
STDIN 一个已打开的指向 stdin 的流。可以用如下方法来调用:
<?php
$stdin = fopen('php://stdin', 'r'
);
?>
如果想从 stdin 读取一行内容,可以使用
<?php
$line = trim(fgets(STDIN)); 
// 从 STDIN 读取一行
fscanf(STDIN, "%d ", $number); 
// 从 STDIN 读取数字
?>
STDOUT 一个已打开的指向 stdout 的流。可以用如下方式来调用:
<?php
$stdout = fopen('php://stdout', 'w'
);
?>
STDERR 一个已打开的指向 stderr 的流。可以用如下方式来调用:
<?php
$stderr = fopen('php://stderr', 'w'
);
?>

有了以上常量,就无需自己建立指向诸如 stderr 的流,只需简单的使用这些常量来代替流指向:

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


无需自己来关闭这些流,PHP 会自动完成这些操作。

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

以下范例显示了本模块与 CGI SAPI 模块之间的不同:

<?php //名为 test.php 的简单测试程序 echo getcwd(), " "; ?>


在使用 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 编写外壳工具时获得了很大的便利。 

Note:

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

    以下是 PHP 二进制文件(即 php.exe 程序)提供的命令行模式的选项参数,随时可以运行带 -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 <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 Display colour syntax highlighted source. -v Version number -w Display 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

    
    

     

    win 下使用CIL(即php.exe二进制文件)

    在我的个人电脑上,操作系统是 windows xp,在F:APMServ5.2.6PHP目录下 php.exe

    图文教程:

    方法一:

    电脑左下角,开始->运行 输入 cmd 回车

    输入 f: 回车
    输入 cd APMServ5.2.6PHP 回车

    输入 php -h 回车

     

    方法二:

    把php.exe文件所在的目录,添加到系统变量中。如图

    以后再 开始->运行 直接输入命令使用即可,例如输入 php -h 回车 再输入ctl+c,就会得到结果

     

    运行PHP文件

    你可以编辑PHP文件test.php(随便放哪儿,如d盘下)

    <?php
    echo "test by www.phpddt.com";
    ?>

    那么你在cmd中就可以这样运行:
    php d:test.php

    如下:

    在命令行下运行PHP结果

    注意:这里寻找php文件就是用物理路径了。

     

    PHP-CLI模式的优势及使用场合:

    • 1.完全支持多线程
    • 2.如上,可以实现定时任务
    • 3.开发桌面应用就是使用PHP-CLI和GTK包
    • 4.linux下用php编写shell脚本


    其实PHP的运行环境远远不止apache和cli的,哈哈,如aolserver, apache, apache2filter, apache2handler, caudium, cgi (until PHP 5.3), cgi-fcgi, cli, continuity, embed, isapi, litespeed, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux, and webjames.

    你可以用php_sapi_name()去检测的,不信,看下面这段代码:

    <?php 
    echo php_sapi_name(); 
    

    我在浏览器上运行结果:
    PHP CLI模式介绍及使用教程演示1

     

    我在windows的cmd上运行:

    使用标准的输入输出:
    STDIN  标准输入设备
    STDOUT 标准输出设备
    STDERR 标准错误设备

     

    看看运行下面这段程序的结果就知道了:

    <?php 
    // ask for input 
    fwrite(STDOUT, "Enter your name:"); 
     
    // get input 
    $name = trim(fgets(STDIN)); 
     
    // write input back
    fwrite(STDOUT, "Hello, $name!"); 
    

    运行截图:

    使用命令行自变量:
    PHP CLI带有两个特殊的变量,专门用来达到这个目的:一个是$argv变量,它通过命令行把传递给PHP脚本的参数保存为单独的数组元素;另一个是$ argc变量,它用来保存$argv数组里元素的个数。
    你可以运行:

    <?php 
    print_r($argv);
    

    看结果:
    PHP CLI模式介绍及使用教程演示3

     

    使用PHP CLI传递脚本参数的形式:
    请看参数:

    参数 说明
    -a 交互式运行Run interactively
    -c path 从path读取php的.ini文件
    -n 不用读取php的.ini文件就直接运行
    -m 列出经过编译的模块
    -i 显示有关PHP构建的信息
    -l 检查PHP脚本的句法
    -s 以彩色方式显示源代码
    -w 显示去掉注释之后的源代码
    -h 显示帮助

    PHP CLI模式介绍及使用教程演示4

     

    至此,我对PHP CLI有了一定的认识了,如果读者想要了解更多,请参考官方手册:http://php.net/manual/zh/features.commandline.php