在做开发的时候,咱们不仅仅只是做各种网站或者接口,也常常须要写一些命令行脚本用来解决一些后端的事务。比方对数据进行解决统计等。当然也是为了效率着想,当一个事务有可能会有较长的耗时时,往往会交由服务器的定时器来固定工夫调用脚本进行解决,从而让客户端可能有更好的用户体验。咱们明天就来理解下 PHP 的命令行运行模式,也就是 PHP CLI。
CLI 与 CGI
首先来看一下 CLI 和 CGI 的区别。咱们都晓得,Nginx 应用的是 FastCgi 来调用 PHP 的服务。CGI 是通用编程接口,也就是给调用者提供的一种应用本程序的接口。Nginx 这种类型的服务器并不是间接运行 PHP 程序的,而是通过 FastCgi 来执行 PHP 程序并取得返回后果。
CLI 则是 Command Line Interface,即命令行接口。次要用作 PHP 的开发外壳利用。也就是用 PHP 来进行 shell 脚本的开发。相比 linux 原生的 shell 来说,当然是不便了许多。在命令行状态下,间接应用 php 命令就能够运行某段 PHP 代码或某个 PHP 文件了。
另外,咱们在命令行也能够间接应用 phpcgi 来运行一段 PHP 代码或者某个 PHP 文件,它和间接应用 php 命令来运行有什么区别呢?
- CLI 的输入没有任何头信息
- CLI 在运行时,不会把工作目录改为脚本的当前目录
- CLI 出错时输入纯文本的错误信息(非 HTML 格局)
- 强制笼罩了 php.ini 中的某些设置,因为这些设置在外壳环境下是没有意义的
// PHP 的 CLI 命令行运行模式浅析.php
echo getcwd();
// php-cgi dev-blog/php/202004/source/PHP 的 CLI 命令行运行模式浅析.php
// ...../MyDoc/ 博客文章 /dev-blog/php/202004/source
// php dev-blog/php/202004/source/PHP 的 CLI 命令行运行模式浅析.php
// ...../MyDoc/ 博客文章
咱们选取最典型的一个例子,咱们运行的这个文件中,应用 getcwd() 输入以后脚本运行的目录,能够看出两种运行形式输入的后果显著不同。php-cgi 是以文件所在目录为基准输入,而 php 则是以以后运行这个命令的目录为基准输入。
间接运行 PHP 代码
在做一些简略的调试的时候,咱们能够间接通过 CLI 来运行一段代码。
// php -r "echo 121;"
// 121
也就是简略的加个 -r 参数,前面跟上一段代码,这段代码必须用引号括起来。而且这个引号更举荐应用单引号,前面的例子会展现为什么用单引号更好。
CLI 获取参数
命令行模式下也是能够给脚本传递参数的。
// PHP 的 CLI 命令行运行模式浅析.php
print_r($argv);
// php-cgi dev-blog/php/202004/source/PHP 的 CLI 命令行运行模式浅析.php 1 2 3
// X-Powered-By: PHP/7.3.0
// Content-type: text/html; charset=UTF-8
// php dev-blog/php/202004/source/PHP 的 CLI 命令行运行模式浅析.php 1 2 3
// Array
// (// [0] => dev-blog/php/202004/source/PHP 的 CLI 命令行运行模式浅析.php
// [1] => 1
// [2] => 2
// [3] => 3
// )
在测试文件中,咱们打印了 \$argv 变量。PHP 脚本运行的时候,会将命令行的所有参数保留在 $argv 变量中,并且还有一个 $argc 变量会保留参数的个数。
咱们仍然是应用 php-cgi 和 php,两种模式来测试,从这里咱们能发现 php-cgi 模式中 $argv 打印的内容居然是头信息,而不是具体的参数信息。这也没错,毕竟 CGI 模式原本就是为 Web 服务器提供的接口,所以它接管的是 post、get 这类的参数而不是命令行的参数。
CLI 模式下咱们失常取得了参数内容,并且 $argv[0] 始终保留的是以后运行文件及门路。
CLI 命令行实用选项
最初,咱们再介绍一些命令行中罕用的选项。
-r 间接运行代码时的参数传递
// php -r "var_dump($argv);" app
// Warning: var_dump() expects at least 1 parameter, 0 given in Command line code on line 1
// 双引号 ",sh/bash 履行了参数替换
// php -r 'var_dump($argv);' app
// array(2) {// [0]=>string(19) "Standard input code"
// [1]=>string(3) "app"
// }
// php -r 'var_dump($argv);' -- -h
// array(2) {// [0]=>string(19) "Standard input code"
// [1]=>string(2) "-h"
// }
第一段代码在对双引号运行的 CLI 代码进行参数传递的时候,会间接报正告。其实很好了解,双引号外面的 $ 会让零碎的 sh/bash 认为这是个变量从而进行变量参数替换。所以更举荐应用单引号进行日常的简略测试。
第二段代码可能失常打印传递进来的参数内容。第三行代码则是须要传递带 – 符号的内容时,须要先给一个 — 参数列表分隔符。这是因为 -xxx 的内容会让 php 命令认为这是一个命令选项而不是参数,所以咱们增加一个分隔符就能够让分隔符之后的参数内容原样传递进代码中。
交互式地运行 PHP
// php -a
// php > $a = 1;
// php > echo $a;
// php > 1
增加一个 -a 选项,PHP 就会以交互式地模式运行,咱们能够间接在交互状态下写代码或运行任何内容。
查看 phpinfo() 及曾经装置的模块
这两个应该是大家常常会应用的两个选项。
// 输入 phpinfo()
// php -i
// 输入 PHP 中加载的模块
// php -m
// 查看模块详细信息
// php --ri swoole
另外咱们还能够通过 –ri 模块名 这个命令来查看具体某个扩大模块的详细信息。比方这里咱们能够查看到 swoole 扩大的版本及相干的配置信息。
查看某个文件
// 显示去除了正文和多余空白的源代码
// php -w dev-blog/php/202004/source/PHP 的 CLI 命令行运行模式浅析.php
// <?php
// echo getcwd(); print_r($argv);
// 通过 linux 管道读取输出
// cat dev-blog/php/202004/source/PHP 的 CLI 命令行运行模式浅析.php | php -r "print file_get_contents('php://stdin');"
// ...... 这个文件外面所有的内容
最初两个小技巧,一个是通过 -w 选项,咱们能够打印这个 php 文件中所有非正文和换行的内容。能够看成是像前端的代码压缩一样的能力。咱们这个测试文件中有十分多的正文,通过这个命令后咱们打印进去的内容是去除掉所有正文和空白行的后果。
另一个是咱们能够用 linux 管道的形式向 PHP CLI 发送数据。这里咱们通过 cat 查看咱们的测试文件而后通过管道发送给 PHP CLI,在脚本中应用 STDIN 来读取管道发送过去的内容实现了整个文件内容的打印。这里咱们没进行任何过滤,所以打印的是整个文件外面的内容,大家能够运行这个命令来测试。
总结
其实命令行模式运行的时候还有很多的选项,这里咱们只是选取了一部分十分有用的内容进行展现。当然,大部分框架都提供了用于命令行的脚本框架,比方 laravel 中能够通过 php artisan make:command 来创立命令行脚本,而后应用 php artisan 来运行框架中的脚本。这些内容未来咱们在学习框架方面常识的内容将会进行具体的解说。
命令行 CLI 模式的利用十分宽泛,简直任何我的项目中都会应用到,所以,深刻的学习把握它将会使咱们大受裨益。
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202004/source/PHP%E7%9A%84CLI%E5%91%BD%E4%BB%A4%E8%A1%8C%E8%BF%90%E8%A1%8C%E6%A8%A1%E5%BC%8F%E6%B5%85%E6%9E%90.php
参考文档:
https://www.php.net/manual/zh/features.commandline.php
各自媒体平台均可搜寻【硬核项目经理】