When doing development, we are not just doing various websites or interfaces, It is also often necessary to write some command line scripts to handle some back-end transactions. For example, data processing and statistics. Of course, for the sake of efficiency, when a transaction may take a long time, the server's timer is often used to call the script at a fixed time for processing, so that the client can have a better user experience. Today we will learn about PHP’s command line running mode, which is PHP CLI.
CLI and CGI
First let’s look at the difference between CLI and CGI. We all know that Nginx uses FastCgi to call PHP services. CGI is a universal programming interface, which is an interface provided to the caller to use this program. This type of server, Nginx, does not run PHP programs directly, but uses FastCgi to execute PHP programs and obtain return results.
CLI is Command Line Interface, which is the command line interface. Mainly used as a development shell application for PHP. That is, use PHP to develop shell scripts. Compared with the native Linux shell, it is of course much more convenient. In the command line state, you can run a certain PHP code or a certain PHP file directly using the php command.
In addition, we can also directly use phpcgi on the command line to run a piece of PHP code or a certain PHP file. What is the difference between it and directly using the php command to run it?
The output of CLI does not have any header information
-
CLI will not change the working directory to the current directory of the script when running
CLI outputs plain text error messages (non-HTML format) when an error occurs
Forcibly overrides certain settings in php.ini because these settings It is meaningless in a shell environment
// 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/博客文章
We choose the most typical example. In the file we run, we use getcwd() to output the directory where the current script is running. It can be seen that The output results of the two running modes are obviously different. php-cgi outputs based on the directory where the file is located, while php outputs based on the directory where the command is currently run.
Run PHP code directly
When doing some simple debugging, we can run a piece of code directly through the CLI.
// php -r "echo 121;" // 121
That is, simply add the -r parameter, followed by a piece of code, which must be enclosed in quotation marks. And it is recommended to use single quotes for this quote. The following examples will show why single quotes are better.
CLI Get Parameters
You can also pass parameters to the script in command line mode.
// 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 // )
In the test file, we printed the \$argv variable. When the PHP script is run, all parameters of the command line will be saved in the $argv variable, and there is also an $argc variable that will save the number of parameters.
We still use php-cgi and php, two modes for testing. From here we can find that the content printed by $argv in php-cgi mode is actually header information, not specific parameter information. This is correct, after all, the CGI mode is originally an interface provided for the web server, so it receives parameters such as post and get instead of command line parameters.
In CLI mode, we obtain the parameter content normally, and $argv[0] always saves the current running file and path.
CLI command line practical options
Finally, we will introduce some commonly used options in the command line.
-r Parameter passing when running the code directly
// 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" // }
The first piece of code will directly report a warning when passing parameters to the CLI code running in double quotes. In fact, it is easy to understand. The $ in double quotes will make the system's sh/bash think that this is a variable and replace the variable parameters. Therefore, it is more recommended to use single quotes for daily simple testing.
The second piece of code can print the passed parameter content normally. The third line of code requires that when content with the - symbol needs to be passed, a -- parameter list separator needs to be given first. This is because the content of -xxx will make the php command think that this is a command option rather than a parameter, so we add a delimiter to pass the parameter content after the delimiter into the code as it is.
Run PHP interactively
// php -a // php > $a = 1; // php > echo $a; // php > 1
Add a -a option, and PHP will run interactively. We can write code or run anything directly in the interactive state.
View phpinfo() and installed modules
These two should be the two options that everyone often uses.
// 输出 phpinfo() // php -i // 输出 PHP 中加载的模块 // php -m // 查看模块详细信息 // php --ri swoole
In addition, we can also use the --ri module name command to view the detailed information of a specific extension module. For example, here we can view the swoole extension version and related configuration information.
查看某个文件
// 显示去除了注释和多余空白的源代码 // 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
推荐学习:php视频教程