php cli编程 命令行模式相关知识点

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/mrtwenty/article/details/99941674

在命令行下执行php脚本,一般我们可以这么做:

1、demo1.php

<?php
echo "hello php\n";

然后执行脚本就是:

php demo1.php

执行结果:

2、demo2.php ,执行 

which php

查看php脚本命令在哪里,例如我的就是: /usr/local/php/bin/php,那我们就可以这么写demo2.php:

#!/usr/local/php/bin/php
<?php
echo "hello php\n";

然后执行 chmod +x demo2.php ,将demo2.php设置成可执行文件,就跟我们写shell一样的方式,执行脚本就无需前缀php了,直接 ./demo2.php 即可。

./demo2.php

两种方式都可以,一般写的php脚本是用于crontab定时任务,建议采用第二种方式编写。

现在我们来介绍相关知识点:

1、cli编程,命令行模式下, cookie、session这些机制都是没用的,所以不要使用这些内置的超全局变量。session_start 也是白费劲的,会生成session文件,下次执行又会生成一个文件,浪费性能不说,session文件还占空间。下面举一个反例子,切记,不要这么用:

<?php
session_save_path(__DIR__);
session_start();

执行两次 php demo3.php ,然后 ll 查看文件列表,会多出两个没用的session文件。

2、set_time_limit 无效,命令行模式本身是无超时机制的,所以无需这么写了。

3、PHP版本判断,PHP_VERSION常量 、version_compare 函数,可以方便我们做一些兼容性处理,这不仅仅可以用在cli上。

下面就是一个例子,php7.1.0 提供了一个新的函数,pcntl_async_signals 用来代替  pcntl_signal_dispatch ,为了兼容低版本的php,我们可以这么写,以便兼容多个版本。

#!/usr/local/php/bin/php
<?php
 
if(version_compare(PHP_VERSION, '7.1.0')>=0){
    pcntl_async_signals(true);
}
 
pcntl_signal(SIGINT, function(){
   echo "信号触发\n";
});
 
 
$i=0;
while(true){
    if(version_compare(PHP_VERSION, '7.1.0')<0){
        pcntl_signal_dispatch();
    }
    $i++;
    echo $i,"\n";
    sleep(1);    
}

4、设置进程名 cli_set_process_title、setproctitle ,执行php脚本的时候,我们可以利用下面的代码,给我们的进程设置名字,方便我们的查找和判断,例如一个长时间执行的脚本,一次只能执行一个,不能重复执行,我们可以给程序设置名字,执行的时候,查询下,当前进程是否有执行的进程名,即可判断是否重复执行了。

<?php

$pid = trim(`pidof learnPHPcli`);
if (!empty($pid)) {
    exit('sorry');
}

function set_process_title($title)
{
    set_error_handler(function () {});
    // >=php 5.5
    if (function_exists('cli_set_process_title')) {
        cli_set_process_title($title);
    } // Need proctitle when php<=5.5 .
    elseif (extension_loaded('proctitle') && function_exists('setproctitle')) {
        setproctitle($title);
    }
    restore_error_handler();
}

set_process_title("learnPHPcli");

//执行自己的业务,上面的代码, 为了保证不重复执行。
echo "run";
sleep(10);

5、php_sapi_name函数 运行模式检查,判断是否是 cli执行,为了避免脚本乱用,cli代码不能跑在php-fpm模式下,

<?php
// 当然也可以用 PHP_SAPI 判断
if (php_sapi_name() != "cli") {
   exit("only run in cli \n");
}

6、判断当前系统是否满足你的代码要求,如果只能是linux执行,可以使用常量 PHP_OS或者是DIRECTORY_SEPARATOR

<?php
if (DIRECTORY_SEPARATOR === '\\') {
    exit('only run Unix-like');
}

7、register_argc_argv 设置被设置为true,所以我们可以使用 $argv $argc 变量,来获取外部提交的参数个数和值。

<?php
function test(){
  global $argc,$argv;
  echo $argc."\n";
  print_r($argv);
}

test();

执行命令:

php demo4.php hehe haha

结果如下:

8、当然还有个函数 getopt 也是可以用来获取参数,可以获取 -a --h 这些命令行参数的

<?php

$options="a:";
$longopts=["help:"];
 
$result= getopt($options,$longopts);

var_dump($result);

执行的时候,就可以使用参数:

php demo5.php -a test --help long

结果如下:

9、cli模式下,php帮我们定义了三个常量: STDIN 、STDOUT、STDERR 用来做标准输入、标准输出、标准错误,我们打印下,其实就是三个资源句柄:

<?php
var_dump(STDIN,STDOUT,STDERR);

我们可以使用STDIN来接收客户端的输入,例如:

<?php
$res1= trim(fgets(STDIN));
$res2= trim(fgets(STDIN));
echo $res1,$res2,"\n";

执行:  

php demo7.php

然后可以输入两个值,以换行回车区分

使用STDOUT 和STDERR来输出标准输出和标准错误:

<?php

 fwrite(STDOUT,"标准输出\n");
 fwrite(STDERR,"标准错误\n");

用于标准输出和标准错误都是输出到终端的,我们可以使用重定向,将他们重定向到别的地方:

php demo8.php 1>>out 2>>err

例如上面的例子,就是将标准输出重定向到文件out,将标准错误重定向到文件err。

10、查看扩展模块是否存在可以使用php -m |grep "name" 的方式处理。

php -m|grep pcntl

11、查看php的配置文件,可以使用 php --ini 的方式查找

 

可以看到我的环境配置文件存放于:

/usr/local/php/etc/php-cli.ini 

在php的配置目录中,我们可以设置两个php.ini文件,一个是 php.ini ,一个是 php-cli.ini ,一个对应web的php-fpm、一个是对应cli模式的配置,这样两者区分开来,web模式下的php.ini,我们可以配置禁用掉一些不怎么需要,有可能导致安全问题的函数或者类。

猜你喜欢

转载自blog.csdn.net/mrtwenty/article/details/99941674