• PHP 命令行模式实战之cli+mysql 模拟队列批量发送邮件(在Linux环境下PHP 异步执行脚本发送事件通知消息实际案例)


    源码地址:https://github.com/Tinywan/PHP_Experience

    测试环境配置:

    1. 环境:Windows 7系统 、PHP7.0、Apache服务器
    2. PHP框架:ThinkPHP框架(3.2)
    3. Redis数据库:测试数据回调函数:通过一个Redis的自增incr来测试异步脚本执行的次数和访问的时间(平时都是用Redis测试写日志的)
    4. 编辑器:Visual Studio Code (CLI运行环境好看点)

    PHP 的命令行模式

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

    PHP命令行(CLI)参数详解

    -a               以交互式shell模式运行
    -c | 指定php.ini文件所在的目录
    -n               指定不使用php.ini文件
    -d foo[=bar]     定义一个INI实体,key为foo,value为'bar'
    -e               为调试和分析生成扩展信息
    -f         解释和执行文件.
    -h               打印帮助
    -i               显示PHP的基本信息
    -l               进行语法检查 (lint)
    -m               显示编译到内核的模块
    -r         运行PHP代码,不需要使用标签 ..?>
    -B   在处理输入之前先执行PHP代码
    -R         对输入的没一行作为PHP代码运行
    -F         Parse and execute  for every input line
    -E     Run PHP  after processing all input lines
    -H               Hide any passed arguments from external tools.
    -S : 运行内建的web服务器.
    -t      指定用于内建web服务器的文档根目录
    -s               输出HTML语法高亮的源码
    -v               输出PHP的版本号
    -w               输出去掉注释和空格的源码
    -z         载入Zend扩展文件 .
    
    args...          传递给要运行的脚本的参数. 当第一个参数以-开始或者是脚本是从标准输入读取的时候,使用--参数
    
    --ini            显示PHP的配置文件名
    
    --rf       显示关于函数  的信息.
    --rc       显示关于类  的信息.
    --re       显示关于扩展  的信息.
    --rz       显示关于Zend扩展  的信息.
    --ri       显示扩展  的配置信息.

    启动内建web服务器,并且默认以当前目录为工作目录:

    PHP 7.0.10 Development Server started at Sun Feb 26 17:48:25 2017
    Listening on http://localhost:8000
    Document root is E:wamp64wwwcli
    Press Ctrl-C to quit.

    查找PHP的配置文件

      在有的时候,由于服务器上软件安装比较混乱,我们可能安装了多个版本的PHP环境,这时候,如何定位我们的PHP程序使用的是那个配置文件就比较重要了。在PHP命令行参数中,提供了–ini参数,使用该参数,可以列出当前PHP的配置文件信息。

    上述的服务器上我们安装了两个版本的PHP,由上可以看到,使用php –ini命令可以很方便的定位当前PHP命令将会采用哪个配置文件。

     查看类/函数/扩展信息

      通常,可以使用php –info命令或者在在web服务器上的php程序中使用函数phpinfo()显示php的信息,然后再查找相关类、扩展或者函数的信息,这样做实在是麻烦了一些。

    我们可以使用下列参数更加方便的查看这些信息

    --rf       显示关于函数  的信息.
    --rc       显示关于类  的信息.
    --re       显示关于扩展  的信息.
    --rz       显示关于Zend扩展  的信息.
    --ri       显示扩展  的配置信息.

    查看扩展redis的配置信息

    查看redis类的信息

    查看函数printf的信息

    语法检查

      有时候,我们只需要检查php脚本是否存在语法错误,而不需要执行它,比如在一些编辑器或者IDE中检查PHP文件是否存在语法错误。使用-l(–syntax-check)可以只对PHP文件进行语法检查:

    假如此时我们的index.php中存在语法错误

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

    1. 完全支持多线程

    2. 实现定时任务

    3. 开发桌面应用就是使用PHP-CLI和GTK包

    4. linux下用php编写shell脚本

    PHP 的命令行模式扩展

      其实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()这个函数去检测,这里只检测Apache服务器和Windows CMD扩展,下面编写一个cli.php文件进行测试:

    <?php
    echo "PHP current cli mode :".php_sapi_name();

    Windows cmd命令行模式运行结果:

    在Apache服务器模式下运行结果:

    PHP 的命令行自变量

      和所有的外壳应用程序一样,PHP 的二进制文件(php.exe 文件)及其运行的 PHP 脚本能够接受一系列的参数。PHP 没有限制传送给脚本程序的参数的个数(外壳程序对命令行的字符数有限制,但通常都不会超过该限制)。传递给脚本的参数可在全局变量 $argv 中获取。该数组中下标为零的成员为脚本的名称(当 PHP 代码来自标准输入获直接用 -r 参数以命令行方式运行时,该名称为“-”)。另外,全局变量 $argc 存有 $argv 数组中成员变量的个数(而非传送给脚本程序的参数的个数)。

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

    建立一个测试文件cli.php:

    <?php
    echo "argv:".print_r($argv)."
    ";
    echo "argc:".$argc;

    测试结果如下所示:

     

    了解更多,请参考官方手册:http://php.net/manual/zh/features.commandline.php

    至此,PHP 命令行模式基本知识已介绍完毕!

    下面进入实战模式:

    环境介绍,Wamp环境,ThinkPHP 3.2 框架的cli模式

    首先在应用程序(我这里的是:Backend)的下新建一个Library模块,在该模块中新建一个Index控制器,新建一个cmdCliTest方法,如下所示

    // 定义应用目录
    define('APP_PATH',dirname(__FILE__).'/Backend/');
    // 定义CLI运行模式运行的项目路径
    define('CLI_PATH',dirname(__FILE__)."\");

     cmdCliTest方法文件内容如下所示:

        //这个方法将被cli模式调用
        public function cmdCliTest()
        {
             echo date("Y-m-d H:i:s",time()).' : ThinnPHP cli Mode Run Success:';
        }

    第一种,使用Apache服务器方式访问该方法,输出结果:

    第二种,首先CMD到当前项目目录!!!,下面使用命令行模式输出结果:

    第三种,通过Apache服务器方式运行命令行模式,这里就要涉及到一个PHP系统函数exec(),在当前控制器(Library模块index控制器)新建一个测试方法apacheToCli

        //通过APache 服务器方式启动一个CLi进程
        public function apacheToCli()
        {
            // echo CLI_PATH."cli.php Library/index/test";
            echo '------------------------------------启动一个CLi进程 开始--------------------------------';
            exec("E:wamp64inphpphp7.0.10php.exe E:wamp64wwwThinkPhpStudycli.php /Library/index/cmdCliTest 2>&1",$output, $return_val);
            echo "<hr/>"; 
            var_dump($output);  //命令执行后生成的数组
            echo "<hr/>";
            var_dump("执行的状态:".$return_val); //执行的状态
            echo '-----------------------------------启动一个CLi进程 结束----------------------------------';
        }

     cmdCliTest方法:

        //这个方法将被cli模式调用
        public function cmdCliTest()
        {
             sleep(10); //方便我们在任务管理器查看PHP cli进程,
             echo date("Y-m-d H:i:s",time()).' cmdCliTest()这个方法将被cli模式调用: ThinnPHP cli Mode Run Success:';
        }

      这时候我们在Apache服务器模式下测试,可以看出在Apache服务器模式下运行的时候通过系统函数exec()成功的启动了一个php cli 进程,同时打印出了cli命令行模式执行后的结果通过第二个变量存储的$output中,打印出了返回的结果,同时第三个参数的执行装填也是:0(表示成功)

    PHP的exec()函数无返回值排查方法

    exec执行某命令在命令行下没有问题,但是在PHP中就出错。这个问题99.99%与权限有关,但是exec执行的命令不会返回错误。一个技巧就是使用管道命令,假设你的exec调用如下:

     exec("E:wamp64inphpphp7.0.10php.exe E:wamp64wwwThinkPhpStudycli.php /Library/index/cmdCliTest",$output, $return_val);

    可以更改如下:

     exec("E:wamp64inphpphp7.0.10php.exe E:wamp64wwwThinkPhpStudycli.php /Library/index/cmdCliTest 2>&1",$output, $return_val);
     var_dump($output);
     var_dump($return_val);

    使用 2>&1, 命令就会输出shell执行时的错误到$output变量, 输出该变量即可分析。

    注意: exec有3个参数,第一个是要执行的命令,第二个是参数是一个数组,数组的值是由第一个命令执行后生成的,第三个参数执行的状态,0表示成功,其他都表示失败。在php里面一共有三个函数可以用来执行外部命令system,exec,passthru。

    PHP 执行shell脚本的返回值

    exec执行一个shell 脚本:

    $cmdStr = "ffmpeg/script/check_location_cut.sh {$activityid2} {$sourcefile} {$starttime} {$endtime} {$editid} {$video_desc}";
    exec("{$cmdStr}",$output, $sysStatus);

      第一次执行这个脚本的时候,脚本中的命令是执行成功的,但是每次回调的状态码 $sysStatus 一直是1 而不是0(表示成功),最终的原因是在shell脚本最后的返回值出现了错误:exit 1 其实在这里exit 1 表示的是错误的输出。所以在这里修改为 exit 0 则就是没有错误信息了

      exit 命令同于退出shell,并返回给定值。在shell脚本中可以终止当前脚本执行。执行exit可使shell以指定的状态值退出。若不设置状态值参数,则shell以预设值退出。状态值0代表执行成功,其他值代表执行失败。

    更多:Linux命令exit – 退出当前shell

    PHP+Mysql批量发送邮件

    关于发送邮件的见另外一篇博客:http://www.cnblogs.com/tinywan/p/5868013.html

    两个方法代码(Windows 环境测试,如果是Linux测试环境的话,请看后面相关内容

        //
        public function apacheToCliEmail()
        {
            echo '------------------------------------启动一个CLi进程 开始--------------------------------';
            exec("E:wamp64inphpphp7.0.10php.exe E:wamp64wwwThinkPhpStudycli.php /Library/Email/taskTable 2>&1", $output, $return_val);
            echo "<hr/>";
            var_dump($output);  //命令执行后生成的数组
            echo "<hr/>";
            var_dump("执行的状态:" . $return_val); //执行的状态
            echo '-----------------------------------启动一个CLi进程 结束----------------------------------';
        }

    命令行模式cli 需要执行的方法(命令行下为一个文件,不一定是php文件)

      //cli 命令行需要执行的php文件
        public function taskTable()
        {
            $model = M("TaskList");
            $status = 0;
            $conditions = array('status' => ':status');
            $result = $model->where($conditions)->bind(':status', $status)->select();
            if (empty($result)) exit('没有可发送的邮件');
            echo '开始发送邮件:' . "
    ";
            foreach ($result as $key => $value) {
                //发送邮件
                $result = send_email($value['user_email'], 'Tinywan激活邮件', "https://github.com/Tinywan");
                //发送成功
                if ($result['error'] == 0) {
                    //修改数据库字段status 的值为1
                    $model->where(array('id' => $value['id']))->setField('status', 1);
                }
                sleep(10);
                //其实在这里可以添加一个状态表示没有发送成功的标记,修改数据库字段status 的值为2
                //$model->where(array('id' => $value['id']))->setField('status', 2);
            }
            exit('发送邮件结束');
        }

    测试结果:

    发送邮件的方法

    /**
     * 发送邮件
     * @param  array $address 需要发送的邮箱地址 发送给多个地址需要写成数组形式
     * @param  string $subject 标题
     * @param  string $content 内容
     * @return array  放回状态吗和提示信息
     */
    function send_email($address, $subject, $content)
    {
        $email_smtp = C('EMAIL_SMTP');
        $email_username = C('EMAIL_USERNAME');
        $email_password = C('EMAIL_PASSWORD');
        $email_from_name = C('EMAIL_FROM_NAME');
        if (empty($email_smtp) || empty($email_username) || empty($email_password) || empty($email_from_name)) {
            return ["error" => 1, "message" => '邮箱请求参数不全,请检测邮箱的合法性'];
        }
        $phpmailer = new PHPMailer();
        //     设置PHPMailer使用SMTP服务器发送Email
        $phpmailer->IsSMTP();
        //     设置为html格式
        $phpmailer->IsHTML(true);
        //     设置邮件的字符编码'
        $phpmailer->CharSet = 'UTF-8';
        // 设置SMTP服务器。
        $phpmailer->Host = $email_smtp;
        // 设置为"需要验证"
        $phpmailer->SMTPAuth = true;
        // 设置用户名
        $phpmailer->Username = $email_username;
        // 设置密码
        $phpmailer->Password = $email_password;
        // 设置邮件头的From字段。
        $phpmailer->From = $email_username;
        // 设置发件人名字
        $phpmailer->FromName = $email_from_name;
        // 添加收件人地址,可以多次使用来添加多个收件人
        if (is_array($address)) {
            foreach ($address as $addressv) {
                //验证邮件地址,非邮箱地址返回为false
                if(false === filter_var($address,FILTER_VALIDATE_EMAIL)){
                    return ["error" => 1, "message" => '邮箱格式错误'];
                }
                $phpmailer->AddAddress($addressv);
            }
        } else {
            //验证邮件地址,非邮箱地址返回为false
            if(false === filter_var($address,FILTER_VALIDATE_EMAIL)){
                return ["error" => 1, "message" => '邮箱格式错误'];
            }
            $phpmailer->AddAddress($address);
        }
        // 设置邮件标题
        $phpmailer->Subject = $subject;
        // 设置邮件正文,这里最好修改为这个,不是boby
        $phpmailer->MsgHTML($content);
        // 发送邮件。
        if (!$phpmailer->Send()) {
            return ["error" => 1, "message" => $phpmailer->ErrorInfo];
        }
        return ["error" => 0];
    }

    PHP 异步执行脚本

      这里说的异步执行是让PHP脚本在后台挂起一个执行具体操作的脚本,主脚本退出后,挂起的脚本还能继续执行。比如执行某些耗时操作或可以并行执行的操作,可以采用php异步执行的方式。主脚本和子脚本的通讯可以采用外部文件或memcached的方式。原理就是通过exec或system来执行一个外部命令。注意:在这里所述的是针对Linux环境(不是Windows 环境哦!)

      在Linux下要让一个脚本挂在后台执行可以在命令的结尾加上一个 “&” 符号,有时候这还不够,需要借助nohup命令,这个命令下面有专门的介绍

      Cli环境和Web环境执行的操作还不太一样。先来说CLI环境,这里需要用上nohup和&,同时还要把指定输出,如果不想要输出结果,可以把输出定向到/dev/null中。现在来做一个测试,假设在一个目录中有main.php、sub1.php和sub2.php,其中sub1和sub2内容一样都让sleep函数暂停一段时间。代码如下:

    //main.php
    <?php
        $cmd = 'nohup php ./sub.php >./tmp.log  &';
        exec($cmd);
        $cmd = 'nohup php ./sub1.php >/dev/null  &';
        exec($cmd);
    ?>
    //sub1.php sub2.php
    <?php
        sleep(100000);
    ?>

      上述文件中main.php是作为主脚本,在命令行中执行php main.php,可以看到main.php脚本很快就执行完并退出。在使用ps aux | grep sub命令搜索进程,应该可以在后台看到上述的两个子脚本,说明成功挂起了子脚本。

      在Web环境下,执行php脚本都是Web服务器开启的cgi进程来处理,只要脚本不退出,就会一直占有该cgi进程,当启动的所有cgi进程都被占用完后就不能在处理新的请求。所以对那些可能会很费时的脚本,可以采用异步的方式。启动子脚本的方式和CLI差不多,必须要使用&和指定输出(只好是定向到/dev/null),但是不能使用nohup。例如:

    <?php
        $cmd = 'php PATH_TO_SUB1/sub1.php >/dev/null  &';
        exec($cmd);
        $cmd = 'php PATH_TO_SUB1/sub2.php >/dev/null  &';
        exec($cmd);
    ?>

    当在浏览器中访问该脚本文件,可以看到浏览器里面响应完成,同时使用ps命令查看后台可以看到sub1和sub2脚本。注意上述例子中如果php命令不在PATH中,需要指定命令完整的路径。推荐使用完整路径,特别是在Web下。

    nohup命令及其输出文件

      今天在linux上部署wdt程序,在SSH客户端执行./start-dishi.sh,启动成功,在关闭SSH客户端后,运行的程序也同时终止了,怎样才能保证在推出SSH客户端后程序能一直执行呢?通过网上查找资料,发现需要使用nohup命令。完美解决方案:nohup ./start-dishi.sh >output 2>&1 & ,现对上面的命令进行下解释:

    • 用途:不挂断地运行命令。
    • 语法:nohup Command [ Arg ... ] [ & ]
    • 描述:nohup 命令运行由 Command 参数和任何相关的 Arg 参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & ( 表示“and”的符号)到命令的尾部。

    操作系统中有三个常用的流:

    • 0:标准输入流 stdin
    • 1:标准输出流 stdout
    • 2:标准错误流 stderr

      一般当我们用 > console.txt,实际是 1>console.txt的省略用法;< console.txt ,实际是 0 < console.txt的省略用法。

    测试案例结果:

    ww@iZ232eoxo41Z:~/tinywan $ nohup ./start-dishi.sh >output 2>&1 &

    说明:

    1. 带&的命令行,即使terminal(终端)关闭,或者电脑死机程序依然运行(前提是你把程序递交到服务器上)。
    2. 2>&1的意思是把标准错误(2)重定向到标准输出中(1),而标准输出又导入文件output里面,所以结果是标准错误和标准输出都导入文件output里面了。 至于为什么需要将标准错误重定向到标准输出的原因,那就归结为标准错误没有缓冲区,stdout有。这就会导致 >output 2>output 文件output被两次打开,而stdout和stderr将会竞争覆盖,这肯定不是我门想要的。
    3. /dev/null文件的作用,这是一个无底洞,任何东西都可以定向到这里,但是却无法打开。 所以一般很大的stdou和stderr当你不关心的时候可以利用stdout和stderr定向到这里:./command.sh >/dev/null 2>&1 

    注意:这就是为什么有人会写成: nohup ./command.sh >output 2>output出错的原因了

    =============在Linux环境下PHP 异步执行脚本发送事件通知消息(实践)===============

      需求(思想中心):很多客户会担心消息丢了怎么办,比如客户的服务器宕机了一下会儿,消息会不会丢失呢?为了保证消息可靠性保证机制是基于简单重传实现的,即:如果一条通知消息没有成功发送到您指定的回调URL,反复重试100次(自定义次数)。那怎么确认消息是已经送达您的服务器(客户端)了呢?这里是需要您的协助的:当您的服务器成功收到一条http事件通知消息时,例如在请求的URl中请求成功的时候返回一个字段,0表示客户端服务器已经接受到服务器发送的事件通知消息了,这时候脚本符合条件直接退出脚本执行即可(也就是后台运行的Cli php 后台程序)

    测试环境配置:

    1. 环境:Linux(ubuntu 14.04) ,必须的安装好PHP的WEB环境和CLI环境
    2. PHP框架:Phalcon框架(3.0)
    3. Redis数据库:测试数据回调函数:通过一个Redis的自增incr来测试异步脚本执行的次数和访问的时间(平时都是用Redis测试写日志的)

    Server 服务器端的执行代码

      //CLI模式,模拟队列的形成
        public function listExecAction()
        {
            $streamName = 4001488177666;
            $fileSize = 123.001;
            $duration = 123;
            $video_url = "http://ip/data/{$streamName}/video/{$streamName}.mp4";
            $callBackUrl = "http://ip/openapi/videoCallbackFunction?streamName={$streamName}&fileSize={$fileSize}&duration={$duration}&video_url={$video_url}";
            echo '------------------------------------启动一个CLi进程 开始--------------------------------' . date("Y-m-d H:i:s");
            exec("/usr/bin/php /home/www/tinywan/cli_demo.php '{$callBackUrl}' >/dev/null 2>&1 &");
            echo "<hr/>";
            echo '-----------------------------------启动一个CLi进程 结束----------------------------------' . date("Y-m-d H:i:s");
            die;
        }

      Cli.php执行脚本代码,通过使用CURL的PHP扩展完成一个HTTP请求(GET方式),默认最大发送请求1000次,如果客户端已经接受到事件通知信息了,则立马跳出while循环,当然了后台脚本也就会执行结束了,如果客户端服务器返回状态JSON字符串值为0,则表示客户服务器成功的接受到了事件通知信息,这时候符合第二个条件,则立马跳出循环,停止后台脚本的执行。

    <?php
    $count = 0;
    while (true) {
        $count++;
        $ch = curl_init() or die (curl_error());
        curl_setopt($ch, CURLOPT_URL, $argv[1]);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);
        $response = curl_exec($ch);
        curl_close($ch);
        if ($count > 1000) {
            break;
        }
        //解析JSON字符串为数组
        $res = json_decode($response, true);
        //如果客户端返回数据为0 则表示接收到数据了
        if ($res[0] == '0') {
            break;
        }
        continue;
    }
    exit(1);

      Client客户服务器 模拟一个客户端程序代码(我这里是测试回调的),以下代码用来接受PHP异步执行的脚本返回的参数,同时存储在Redis数据库中去,这里做了一个自增字段VideoId,用来记录脚本执行的次数(当然你也可以直接在命令行里面写一个sleep()函数用来做测试的)

        /**
         * 默认的录像回调函数
         */
        public function videoCallbackFunctionAction()
        {
            $this->view->disable();
            $streamName = $this->request->getQuery("streamName");
            $videoId = $this->request->getQuery("videoId");
            $endTime = $this->request->getQuery("endTime");
            $fileName = $this->request->getQuery("fileName");
            $baseName = $this->request->getQuery("baseName");
            $fileSize = $this->request->getQuery("fileSize");
            $duration = $this->request->getQuery("duration");
    
            $redis = $this->Redis();
            $redis->select(8);
            $incrId = $redis->incr('videoIncrId');
            $redis->hMset('videoCallback:' . $incrId, [
                'streamName' => $streamName,
                'fileName' => $fileName,
                'baseName' => $baseName,
                'fileSize' => $fileSize,
                'time' => date("Y-m-d H:i:s")
            ]);
        }

    =======================================第一次调试=========================================

    echo '------------------------------------启动一个CLi进程 开始--------------------------------' . date("Y-m-d H:i:s");
    exec("nohup /usr/bin/php /home/www/tinywan/cli_demo.php '{$callBackUrl}' >/dev/null 2>&1 &");
    echo "<hr/>";
    echo '-----------------------------------启动一个CLi进程 结束----------------------------------' . date("Y-m-d H:i:s");

    1、测试数据之前先清空Redis数据库数据(命令:FlaushDB ,清空当前数据库的所有key键):

    2、在浏览器刷新执行该脚本程序:

    3、通过: ps -aux | grep php 查看PHP进程

    4、查看Redis数据库信息:

    5、通过以上可以看出。WEB页面并没有一直等待客户端服务器的相应,而是立马结束掉,而同时PHP脚本程序在后台运行,知道跳出循环结束

    6、查看PHP后台基本执行时间为3分钟左右!

     

    ================第二次调试====================修改代码程序:再次调试

    1、测试数据之前先清空Redis数据库数据(命令:FlaushDB ,清空当前数据库的所有key键):

    2、在浏览器刷新执行该脚本程序:

    3、通过: ps -aux | grep php 查看PHP进程

     

    4、查看Redis数据库信息:

    5、通过以上可以看出。WEB页面并没有一直等待客户端服务器的相应,而是立马结束掉,而同时PHP 脚本很快就执行完并退出,立马跳出循环结束(满足条件:$res[0] == 0,客户端服务器返回信息)

    6、查看PHP后台基本执行时间为不到1分钟

    ===============第三次调试====================

    说到这里可能有点怀疑怎么没看到PHP后台进程呢!好,下来我们sleep(10)函数暂停10秒时间,继续测试一下不就知道了,哈哈!

    $count = 0;
    sleep(10);
    while (true) {

    1、步骤同上,清楚Redis数据库数据

     

    2、WEB页面执行结果

    3、PHP后台异步脚本程序

    4、Redis数据库记录数据

     

    测试完毕,可以的,小伙子!棒棒哒!!!!!2017-02-28 16:20:48

  • 相关阅读:
    360给腾讯造的盗梦空间
    C 语言 运算符优先级
    CorelDraw, Adobe Illustrator 转换到 Photoshop 形状路径
    用户体验经典解释
    禁用Windows XP的自动播放功能
    ObjectiveC ARC下的内存管理(一)
    ARC下的内存管理(二)对象及成员的引用关系
    天天撞墙
    PS: 操作不实时显示的解决办法
    摩托罗拉 Milestone新手刷机教程
  • 原文地址:https://www.cnblogs.com/tinywan/p/6443615.html
Copyright © 2020-2023  润新知