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:\wamp64\www\cli
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)."\r\n";
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:\wamp64\bin\php\php7.0.10\php.exe E:\wamp64\www\ThinkPhpStudy\cli.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:\wamp64\bin\php\php7.0.10\php.exe E:\wamp64\www\ThinkPhpStudy\cli.php /Library/index/cmdCliTest",$output, $return_val);

可以更改如下:

 exec("E:\wamp64\bin\php\php7.0.10\php.exe E:\wamp64\www\ThinkPhpStudy\cli.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:\wamp64\bin\php\php7.0.10\php.exe E:\wamp64\www\ThinkPhpStudy\cli.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 '開始發送郵件:' . "\r\n";
        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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM