PHP CLI模式开发

摘要:
可以从$_ SERVER['argv']和$_ SERVER['argc']访问CLI。获取参数的值和数量*一个是$_ SERVER['argv']变量:*另一个是$_ SERVER['argc']变量;它用于保存SERVER['argv']数组中的$_元素数。0表示当前脚本的名称*[1]=&gt//设置错误报告模式$argv=$_ SERVER['argv'];

PHP CLI模式开发不需要任何一种Web服务器(包括Apache或MS IIS等),这样,CLI可以运行在各种场合。
有两种方法可以运行PHP CLI脚本。

第一种方法是使用 # php /path/to/yourFile.php 调用PHP CLI解释器,并给脚本传递参数。这种方法要指定php解释器的路径。
第二种方法是首先运行chmod +x <要运行的脚本文件名>(UNIX/Linux环境),将该PHP文件置为可执行权限,然后在CLI脚本头部第一行加入声明(类似于#! /usr/bin/php 或 PHP CLI 解释器位置),接着在命令行直接执行。

一、从命令行上读取参数
如果想从命令行获取参数,CLI可以从 $_SERVER['argv'] 和 $_SERVER['argc'] 取得参数的值和参数个数。
我们建立一个文件,名字为 cliPHP1.php 脚本代码如下:

#! /usr/local/php/bin/php -q
<?php
/**
 * PHP CLI带有两个特殊的变量,专门用来达到这个目的:
 * 一个是 $_SERVER['argv'] 变量,它通过命令行把传递给PHP脚本的参数保存为单独的数组元素;
 * 另一是 $_SERVER['argc'] 变量,它用来保存$_SERVER['argv']数组里元素的个数。
 *
 *
 * 运行效果:
 * # /usr/local/php/bin/php ./cliPHP1.php  aa bb cc
 * Array
 * (
 *  [0] => ./cliPHP1.php   ---> 0 指当前脚本名称
 *  [1] => aa   --------------> 1 第1个参数
 *  [2] => bb   --------------> 2 第2个参数
 *  [3] => cc   --------------> n 第n个参数
 * )
 * number: 4 -----------------> 参数数量
 * 
 */

ini_set('error_reporting', 'E_ALL & ~E_NOTICE');      //设置错误报告模式

$argv = $_SERVER['argv']; //获取参数(array 数组)
$argc = $_SERVER['argc']; //获取参数数量(integer 整数)

print_r($argv);
echo 'number: '.$argc;
echo "
";
?>


二、处理I/O通道
PHP最初设计不是用于与用户直接的键盘输入或文本输出结合使用。了解这一设计是至关重要的,因为如果需要在命令行中执行任何操作,都必须能够与用户来回通信。
输入输出(I/O)通道这个思想来源于UNIX系统,UNIX系统提供3个文件句柄,用以从一个应用程序及用户终端发送和接收数据。

我们可以把一个脚本的输出重定向到一个文件,例如:
# php world.php > outputfile

如果是在UNIX系统下,也可以使用通道定向到另一个命令或应用程序中。例如:
# php world.php | sort

在PHP 5 CLI中,有一个文件流句柄,可以使用3个系统常量,分别为 STDIN、 STDOUT 和 STDERR。下面我们分别介绍。

(1) STDIN
     STDIN 全称为 standard in 或 standard input 标准输入可以从终端取得任何数据。

(2) STDOUT
     STDOUT 全称为 standard out 或 standard output 标准输出可以直接输出到屏幕(也可以输出到其他程序,使用STDIN取得),如果在PHP CLI模式里使用print或echo语句,则这些数据将发送到STDOUT。

(3) STDERR
     STDERR 全称为 standard error 在默认情况下会直接发送至用户终端,当使用STDIN文件句柄从其他应用程序没有读取到数据时会生成一个“stdin.stderr”。

我们建立一个文件,名字为 cliPHP2.php 脚本代码如下:

#! /usr/local/php/bin/php -q
<?php
/**
 * 本例是一个CLI与用户交互脚本,让其输出用户名与年龄并输出
 * 标准输出: fwrite(STDOUT,'请输出用户名:')    //输出内容
 * 标准输入: fgets(STDIN)                      //获取用户输入的内容
 * 标准错误输出: fwrite(STDERR,'错误:xxxxx')   //输出错误信息
 *
 * 运行效果:
 * [root@zzx tmp]# /usr/local/php/bin/php /wwwroot/test/httpsqs/cliPHP.php
 * Enter your name:
 * Enter your name:zhangsan
 * Enter your age:abc
 * Notice: age must be an integer,try again!
 * Enter your age:aaa  
 * Notice: age must be an integer,try again!
 * Enter your age:22
 * Hello zhangsan, your age is 22 
 */

$name = '';
$age  = '';
while(true){
    fwrite(STDOUT,"Enter your name:");  //标准输出,等待用户输入用户名
    $name = trim(fgets(STDIN));         //标准输入,立即获取用户名
    if(!empty($name)){
        break 1;
    }
}

while(true){
    fwrite(STDOUT,"Enter your age:");
    $age = trim(fgets(STDIN));
    if(empty($age)){
        continue 1;
    }
    $matchNum = preg_match('/^d+$/',$age); //验证整型,获取匹配次数
    if($matchNum == 0){
        fwrite(STDERR,"Notice: age must be an integer,try again!
");          
    }else{
        break 1;
    }
}

//do something here...
$outStr = "Hello $name, your age is $age";
fwrite(STDOUT,$outStr);
echo "

";

?>


三、用 nohup 后台运行CLI
    如果正在运行一个进程,而且在退出账户时该进程还不会结束,即在系统后台或背景下运行,那么就可以使用nohup命令。该命令可以在退出账户之后继续运行相应的进程。
nohup在英文中就是不挂起的意思(no hang up)。该命令的一般形式为:

# nohup <脚本名.php> &

使用nohup命令提交作业,在默认情况下该作业的所有输出都被重定向到一个名为 nohup.out 的文件中,除非另外指定了输出文件:

# nohup /usr/local/php/bin/php ./scriptName.php 1>/tmp/log.txt &                将标准输出重定向到log.txt
# nohup /usr/local/php/bin/php ./scriptName.php 1>/tmp/log.txt 2>/tmp/err.txt & 将标准输出重定向到/tmp/log.txt 错误输出重定向到/tmp/err.txt
# nohup /usr/local/php/bin/php ./scriptName.php 1>/tmp/log.txt 2>&1 &           将标准输出重定向到/tmp/log.txt 然后再将标准错误输出重定向到标准输出,即:两者一起重定向到/tmp/log.txt
# nohup /usr/local/php/bin/php ./scriptName.php 1>/dev/null 2>&1 &              将标准输出和错误输出一起到重定向到/dev/null

这样,PHP CLI脚本执行后的结果将输出到log.txt中,我们可以使用tail命令动态查看内容:
# tail -f -n20 /tmp/log.txt

现在再来实现一个例子,是每隔10秒钟自动生成一个静态HTML文件,并一直执行下去。脚本代码如下:
脚本名称: cliPHP3.php

#! /usr/local/php/bin/php -q
<?php
/**
 * 本例是每隔10秒钟自动生成一个静态HTML文件,并一直执行下去
 */
while(true){
    file_put_contents("/tmp/article_".time().".html",date('Y-m-d H:i:s'));
    sleep(10);             //10秒 (单位: 秒)
    //usleep(1000000 * 0.5); //0.5秒(单位: 微秒 注: 1000000微秒=1秒)
}
?>

保存并且退出vi编辑器,然后赋予 genHTML.php 文件可执行权限,并执行(在Linux命令行下执行脚本建议写绝对路径,这是良好习惯):
# chmod 755 cliPHP3.php
# nohup /usr/local/php/bin/php /wwwroot/httpsqs/cliPHP3.php 1>/dev/null 2>&1 &

执行上述命令后出现如下提示:[2] 3300

在当前会话下,使用jobs命令可以查看所有后台运行的所有进程:
# jobs
[1]-  Running   nohup /usr/local/php/bin/php /wwwroot/httpsqs/usage_server.php > /opt/httpsqs/data/log.txt 2> /opt/httpsqs/data/err.txt &
[2]+  Running   nohup /usr/local/php/bin/php /wwwroot/httpsqs/cliPHP3.php > /dev/null 2>&1 &

如何终止CLI程序的后台运行呢?
使用 # ps aux 可查看当前系统所有进程,使用grep过滤选项即可,如下:
# ps aux | grep php
root      3227  0.1  1.6 106796  8408 pts/3    S    06:03   0:02 /usr/local/php/bin/php /wwwroot/httpsqs/usage_server.php
root      3300  0.0  1.5 106796  8080 pts/3    S    06:39   0:00 /usr/local/php/bin/php /wwwroot/httpsqs/cliPHP3.php
root      3312  0.0  0.1   5980   744 pts/4    S+   06:41   0:00 grep php

能够轻松找到 /wwwroot/httpsqs/cliPHP3.php 对应的PID为3300,使用kill命令杀死进程即可:
# kill 3300

免责声明:文章转载自《PHP CLI模式开发》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇css之背景 | padding | 背景图片 | 位置angular问题总结下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

MySQL的binlog数据如何查看

binlog介绍 binlog,即二进制日志,它记录了数据库上的所有改变. 改变数据库的SQL语句执行结束时,将在binlog的末尾写入一条记录,同时通知语句解析器,语句执行完毕. binlog格式 基于语句,无法保证所有语句都在从库执行成功,比如update ... limit 1; 基于行,将每一次改动记为binlog中的一行.在执行一个特别复杂的...

ORACLE的SPFILE与PFILE

    ORACLE中的参数文件是一个包含一系列参数以及参数对应值的操作系统文件,可以分为两种类型。它们是在数据库实例启动时候加载的,决定了数据库的物理结构、内存、数据库的限制及系统大量的默认值、数据库的各种物理属性、指定数据库控制文件名和路径等信息,是进行数据库设计和性能调优的重要文件。 初始化参数文件(Initialization Parameters...

WPF DataContext与Binding的关系

在前台UI创建一个Label绑定到myLabel <Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsof...

使用shell脚本实现用ping检查刀片服务器与主服务器之间的网络连通

为了检查daq01与刀片服务器之间的网络连接状态, 1. 使用ping命令的输出规律,如果可以ping通,会输出0% packet loss值; 如果不能ping通,则不会输出0% packet loss 2. 若ping命令输出0% packet loss执行成功,则表示网络连接正常,否则网络连接不上 3. shell脚本里的&&与 ||...

Bootstrap风格zTree树形菜单插件

这是一款bootstrap风格jQuery zTree树形菜单插件,支持自定义编辑、添加列表菜单、删除列表等功能的jQuery树形菜单代码。在线演示 具体代码实现: <!DOCTYPE html> <HTML> <HEAD> <TITLE>ZTREE DEMO</TITLE>...

Django用Apache和mod_wsgi部署

背景 最近写了一个Django在windows上运行,但是用的vbs命令,导致在后台运行的时候,必须用户登录才可以运行,还有就是登录之后,有其他进程可能被干掉。 Set ws = CreateObject("Wscript.Shell") ws.run "cmd /c D:\xxd\run.bat",vbhide ` bat 内容 C:\Python3...