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 "\r\n";
?>
二、處理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!\r\n");
}else{
break 1;
}
}
//do something here...
$outStr = "Hello $name, your age is $age";
fwrite(STDOUT,$outStr);
echo "\n\n";
?>
三、用 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

