從版本 4.3.0 開始,PHP 提供了一種新類型的 CLI SAPI(Server Application Programming Interface,服務端應用編程端口)支持,名爲 CLI,意爲 Command Line Interface,即命令行接口。顧名思義,該 CLI SAPI 模塊主要用做 PHP 的開發外殼應用。CLI SAPI 和其它 CLI SAPI 模塊相比有不少的不一樣之處,咱們將在本章中詳細闡述。值得一提的是,CLI和 CGI 是不一樣的 SAPI,儘管它們之間有不少共同的行爲。html
CLI SAPI 最早是隨 PHP 4.2.0 版本發佈的,但仍舊只是一個實驗性的版本,並須要在運行 ./configure 時加上 --enable-cli 參數。從 PHP 4.3.0 版本開始,CLI SAPI 成爲了正式模塊,--enable-cli 參數會被默認得設置爲 on,也能夠用參數 --disable-cli 來屏蔽。mysql
從 PHP 4.3.0開始,CLI/CGI 二進制執行文件的文件名、位置和是否存在會根據 PHP 在系統上的安裝而不一樣。在默認狀況下,當運行 make 時,CGI 和 CLI 都會被編譯而且分別放置在 PHP 源文件目錄的 sapi/cgi/php 和 sapi/cli/php 下。能夠注意到兩個文件都被命名爲了 php。在 make install 的過程當中會發生什麼取決於配置行。若是在配置的時候選擇了一個 SAPI 模塊,如 apxs,或者使用了 --disable-cgi 參數,則在 make install 的過程當中,CLI 將被拷貝到{PREFIX}/bin/php,除非 CGI 已經被放置在了那個位置。所以,例如,若是在配置行中有 --with--apxs ,則在 make install 的過程當中,CLI 將被拷貝到 {PREFIX}/bin/php。若是但願撤銷 CGI 執行文件的安裝,請在 make install 以後運行 make install-cli。或者,也能夠在配置行中加上 --disable-cgi 參數。web
Note:sql
因爲 --enable-cli 和 --enable-cgi 同時默認有效,所以,沒必要再配置行中加上 --enable-cli 來使得 CLI 在 make install 過程當中被拷貝到 {PREFIX}/bin/php。shell
在 PHP 4.2.0 到 PHP 4.2.3 之間的 Windows 發行包中,CLI 的文件名爲 php-cli.exe,相同文件夾下的 php.exe 爲 CGI。從 PHP 4.3.0 版本開始,Windows 的發行包中 CLI 的執行文件爲 php.exe,被放置在一個單獨的名爲 cli 的文件夾下,即 cli/php.exe。在 PHP 5 中,CLI 存在於主文件夾中,名爲 php.exe,而 CGI 版本名爲 php-cgi.exe。編程
從 PHP 5 起,一個名爲 php-win.exe 的新文件隨包發佈。它至關於 CLI 版本,可是 php-win 不輸出任何內容,便不提供控制檯(不會彈出「DOS 窗口」)。這種方式相似於 php-gtk。須要使用 --enable-cli-win32 選項來配置它。api
Note: 如何得知本身使用的是哪一個 SAPI?
數組在命令行下,運行 php -v 便能得知該 php 是 CGI 仍是 CLI。請參考函數 php_sapi_name() 以及常量
PHP_SAPI
。bash
Note:
在 PHP 4.3.2 中加入了 Unix 的 man 頁面。能夠在命令行中鍵入 man php 來查看。
如下爲 CLI SAPI 和其它 CLI SAPI 模塊相比的顯著區別:
與 CGI SAPI 不一樣,其輸出沒有任何頭信息。
儘管 CGI SAPI 提供了取消 HTTP 頭信息的方法,但在 CLI SAPI 中並不存在相似的方法以開啓 HTTP 頭信息的輸出。
CLI 默認以安靜模式開始,但爲了保證兼容性,-q 和 --no-header 參數爲了向後兼容仍然保留,使得可使用舊的 CGI 腳本。
在運行時,不會把工做目錄改成腳本的當前目錄(可使用 -C 和 --no-chdir 參數來兼容 CGI 模式)。
出錯時輸出純文本的錯誤信息(非 HTML 格式)。
CLI SAPI 強制覆蓋了 php.ini 中的某些設置,由於這些設置在外殼環境下是沒有意義的。
設置選項 | CLI SAPI默認值 | 備註 |
---|---|---|
html_errors | FALSE |
無心義的 HTML 標記符會使得出錯信息很凌亂,因此在外殼下閱讀報錯信息是十分困難的。所以將該選項的默認值改成 FALSE 。 |
implicit_flush | TRUE |
在命令行模式下,全部來自 print 和 echo 的輸出將被當即寫到輸出端,而不做任何地緩衝操做。若是但願延緩或控制標準輸出,仍然可使用 output buffering 設置項。 |
max_execution_time | 0(無限值) | 鑑於在外殼環境下使用 PHP 的無窮的可能性,最大運行時間被設置爲了無限值。爲 web 開發的應用程序可能只需運行幾秒鐘時間,而外殼應用程序的運行時間可能會長的多。 |
register_argc_argv | TRUE |
因爲該設置爲 對於 PHP 4.3.0,在使用 CLI SAPI 時,PHP 變量 $argc 和 $argv 已被註冊而且設定了對應的值。而在這以前的版本,這兩個變量在 CGI 或者 模塊 版本中的創建依賴於將 PHP 的設置選項 register_globals 設爲 on。除了版本和register_globals 設定之外,能夠隨時經過調用 $_SERVER 或者 $HTTP_SERVER_VARS 來訪問它們。例如:$_SERVER['argv'] |
Note:
這些設置沒法在設置文件 php.ini 或任何指定的其它文件中被初始化爲其它值。這些默認值被限制在全部其它的設置文件被解析後改變。不過,它們的值能夠在程序運行的過程當中被改變(儘管對於該運行過程來講,這些設置項是沒有意義的)。
爲了減輕外殼環境下的工做,咱們定義了以下常量:
常量名稱 | 描 述 |
---|---|
STDIN |
一個已打開的指向 stdin 的流。能夠用以下方法來調用:
<?php
<?php
|
STDOUT |
一個已打開的指向 stdout 的流。能夠用以下方式來調用:
<?php
|
STDERR |
一個已打開的指向 stderr 的流。能夠用以下方式來調用:
<?php
|
有了以上常量,就無需本身創建指向諸如 stderr 的流,只需簡單的使用這些常量來代替流指向:
php -r 'fwrite(STDERR, "stderr\n");'
CLI SAPI不會將當前目錄改成已運行的腳本所在的目錄。
如下範例顯示了本模塊與 CGI SAPI 模塊之間的不一樣:
<?php // 名爲 test.php 的簡單測試程序 echo getcwd(), "\n"; ?>
在使用 CGI 版本時,其輸出爲
$ pwd /tmp $ php-cgi -f another_directory/test.php /tmp/another_directory
明顯能夠看到 PHP 將當前目錄改爲了剛剛運行過的腳本所在的目錄。
使用 CLI SAPI 模式,獲得:
$ pwd /tmp $ php -q another_directory/test.php /tmp
Note:
能夠在命令行運行時給該 CGI SAPI 加上 -C 參數,使其支持 CLI SAPI 的功能。
如下是 PHP 二進制文件(即 php.exe 程序)提供的命令行模式的選項參數,隨時能夠運行帶 -h 參數的 PHP 命令來查詢這些參數。
Usage: php [options] [-f] <file> [--] [args...] php [options] -r <code> [--] [args...] php [options] [-B <begin_code>] -R <code> [-E <end_code>] [--] [args...] php [options] [-B <begin_code>] -F <file> [-E <end_code>] [--] [args...] php [options] -- [args...] php [options] -a -a Run interactively -c <path>|<file> Look for php.ini file in this directory -n No php.ini file will be used -d foo[=bar] Define INI entry foo with value 'bar' -e Generate extended information for debugger/profiler -f <file> Parse <file>. -h This help -i PHP information -l Syntax check only (lint) -m Show compiled in modules -r <code> Run PHP <code> without using script tags <?..?> -B <begin_code> Run PHP <begin_code> before processing input lines -R <code> Run PHP <code> for every input line -F <file> Parse and execute <file> for every input line -E <end_code> Run PHP <end_code> after processing all input lines -H Hide any passed arguments from external tools. -s Display colour syntax highlighted source. -v Version number -w Display source with stripped comments and whitespace. -z <file> Load Zend extension <file>. args... Arguments passed to script. Use -- args when first argument starts with - or script is read from stdin
CLI SAPI 模塊有如下三種不一樣的方法來獲取要運行的 PHP 代碼:
讓 PHP 運行指定文件。
php my_script.php
php -f my_script.php
以上兩種方法(使用或不使用 -f 參數)都可以運行給定的 my_script.php 文件。能夠選擇任何文件來運行,指定的 PHP 腳本並不是必需要以 .php 爲擴展名,它們能夠有任意的文件名和擴展名。
2.在命令行直接運行 PHP 代碼。
php -r 'print_r(get_defined_constants());'
在使用這種方法時,請注意外殼變量的替代及引號的使用。
Note:
請仔細閱讀以上範例,在運行代碼時沒有開始和結束的標記符!加上 -r 參數後,這些標記符是不須要的,加上它們會致使語法錯誤。
3.經過標準輸入(stdin)提供須要運行的 PHP 代碼。
以上用法提供了很是強大的功能,使得能夠以下範例所示,動態地生成 PHP 代碼並經過命令行運行這些代碼:
$ some_application | some_filter | php | sort -u >final_output.txt
以上三種運行代碼的方法不能同時使用。
和全部的外殼應用程序同樣,PHP 的二進制文件(php.exe 文件)及其運行的 PHP 腳本可以接受一系列的參數。PHP 沒有限制傳送給腳本程序的參數的個數(外殼程序對命令行的字符數有限制,但一般都不會超過該限制)。傳遞給腳本的參數可在全局變量 $argv 中獲取。該數組中下標爲零的成員爲腳本的名稱(當 PHP 代碼來自標準輸入獲直接用 -r 參數以命令行方式運行時,該名稱爲「-」)。另外,全局變量 $argc 存有 $argv 數組中成員變量的個數(而非傳送給腳本程序的參數的個數)。
只要傳送給腳本的參數不是以 - 符號開頭,就無需過多的注意什麼。向腳本傳送以 - 開頭的參數會致使錯誤,由於 PHP 會認爲應該由它自身來處理這些參數。能夠用參數列表分隔符 -- 來解決這個問題。在 PHP 解析完參數後,該符號後全部的參數將會被原樣傳送給腳本程序。
# 如下命令將不會運行 PHP 代碼,而只顯示 PHP 命令行模式的使用說明: $ php -r 'var_dump($argv);' -h Usage: php [options] [-f] <file> [args...] [...] # 如下命令將會把「-h」參數傳送給腳本程序,PHP 不會顯示命令行模式的使用說明: $ php -r 'var_dump($argv);' -- -h array(2) { [0]=> string(1) "-" [1]=> string(2) "-h" }
除此以外,還有另外一個方法將 PHP 用於外殼腳本。能夠在寫一個腳本,並在第一行以 #!/usr/bin/php 開頭,在其後加上以 PHP 開始和結尾標記符包含的正常的 PHP 代碼,而後爲該文件設置正確的運行屬性(例如:chmod +x test)。該方法可使得該文件可以像外殼腳本或 PERL 腳本同樣被直接執行。
#!/usr/bin/php <?php var_dump($argv); ?>
假設改文件名爲 test 並被放置在當前目錄下,能夠作以下操做:
$ chmod +x test $ ./test -h -- foo array(4) { [0]=> string(6) "./test" [1]=> string(2) "-h" [2]=> string(2) "--" [3]=> string(3) "foo" }
正如所看到的,在向該腳本傳送以 - 開頭的參數時,腳本仍然可以正常運行。
PHP 4.3.3 以來有效的長選項:
選項名稱 | 長名稱 | 說明 |
---|---|---|
-a | --interactive | 交互式運行 PHP。若是編譯 PHP 時加入了 Readline 擴展(Windows 下不可用),那將會獲得一個很好的外殼,包括一個自動完成的功能(例如能夠在鍵入變量名的時候,按下 TAB 鍵,PHP 會自動完成該變量名)以及命令歷史記錄,能夠用上下鍵來訪問。歷史記錄存在~/.php_history 文件中。
|
-c | --php-ini | 用該參數,能夠指定一個放置 php.ini 文件的目錄,或者直接指定一個自定義的 INI 文件(其文件名能夠不是 php.ini),例如: $ php -c /custom/directory/ my_script.php $ php -c /custom/directory/custom-file.ini my_script.php |
-n | --no-php-ini | 徹底忽略 php.ini。此參數在 PHP 4.3.0 之後有效。 |
-d | --define | 用該參數能夠自行設置任何能夠在 php.ini 文件中設置的配置選項的值,其語法爲: -d configuration_directive[=value] 例子(因版面緣由而折行顯示): # 取值部分被省略,將會把配置選項設爲 "1" $ php -d max_execution_time -r '$foo = ini_get("max_execution_time"); var_dump($foo);' string(1) "1" # 取值部分爲空白,將會把配置選項設爲 "" php -d max_execution_time= -r '$foo = ini_get("max_execution_time"); var_dump($foo);' string(0) "" # 配置選項將被設置成爲任何 '=' 字符以後的值 $ php -d max_execution_time=20 -r '$foo = ini_get("max_execution_time"); var_dump($foo);' string(2) "20" $ php -d max_execution_time=doesntmakesense -r '$foo = ini_get("max_execution_time"); var_dump($foo);' string(15) "doesntmakesense" |
-e | --profile-info | 激活擴展信息模式,被用於調試/測試。 |
-f | --file | 解析並運行 -f 選項給定的文件名。該參數爲可選參數,能夠省略,僅指明須要運行的文件名便可。 |
-h and -? | --help and --usage | 使用該參數,能夠獲得完整的命令行參數的列表及這些參數做用的簡單描述。 |
-i | --info | 該命令行參數會調用 phpinfo() 函數並顯示出結果。若是 PHP 沒有正常工做,建議執行 php -i命令來查看在信息表格以前或者對應的地方是否有任何錯誤信息輸出。請注意當使用 CGI 摸索時,輸出的內容爲 HTML 格式,所以輸出的信息篇幅較大。 |
-l | --syntax-check | 該參數提供了對指定 PHP 代碼進行語法檢查的方便的方法。若是成功,則向標準輸出寫入 No syntax errors detected in <filename> 字符串,而且外殼返回值爲 0。若是失敗,則輸出 Errors parsing <filename> 以及內部解析器錯誤信息到標準輸出,同時外殼返回值將別設置爲 255。 該參數將沒法檢查致命錯誤(如未定義函數),若是也但願檢測致命錯誤,請使用 -f 參數。
|
-m | --modules | 使用該參數,PHP 將打印出內置以及已加載的 PHP 及 Zend 模塊: $ php -m [PHP Modules] xml tokenizer standard session posix pcre overload mysql mbstring ctype [Zend Modules] |
-r | --run | 使用該參數能夠在命令行內運行單行 PHP 代碼。無需加上 PHP 的起始和結束標識符(<?php 和?>),不然將會致使語法解析錯誤。
|
-B | --process-begin | 在處理 stdin 以前先執行 PHP 代碼。PHP 5 新加。 |
-R | --process-code | 對每一個輸入行都執行 PHP 代碼。PHP 5 新加。 此模式下有兩個特殊變量:$argn 和 $argi。$argn 包含 PHP 當前處理的行內容,而$argi 則包含該行號。 |
-F | --process-file | 對每一個輸入行都執行 PHP 文件。PHP 5 新加。 |
-E | --process-end | 在處理完輸入後執行的 PHP 代碼。PHP 5 新加。 使用 -B ,-R 和 -E 選項來計算一個項目總行數的例子。 $ find my_proj | php -B '$l=0;' -R '$l += count(@file($argn));' -E 'echo "Total Lines: $l\n";' Total Lines: 37328 |
-s | --syntax-highlight and --syntax-highlight | 顯示有語法高亮色彩的源代碼。 該參數使用內建機制來解析文件併爲其生成一個 HTML 高亮版本並將結果寫到標準輸出。請注意該過程所作的只是生成了一個 <code> [...] </code> 的 HTML 標記的塊,並不包含任何的 HTML 頭。
|
-v | --version | 將 PHP,PHP SAPI 和 Zend 的版本信息寫入標準輸出。例如: $ php -v PHP 4.3.0 (cli), Copyright (c) 1997-2002 The PHP Group Zend Engine v1.3.0, Copyright (c) 1998-2002 Zend Technologies |
-w | --strip | 顯示除去了註釋和多餘空白的源代碼。
|
-z | --zend-extension | 加載 Zend 擴展庫。若是僅給定一個文件名,PHP 將試圖從當前系統擴展庫的默認路徑(在 Linux 系統下,該路徑一般由 /etc/ld.so.conf 指定)加載該擴展庫。若是用一個絕對路徑指定文件名,則不會使用系統的擴展庫默認路徑。若是用相對路徑指定的文件名,則 PHP 僅試圖在當前目錄的相對目錄加載擴展庫。 |
PHP 的命令行模式能使得 PHP 腳本能徹底獨立於 web 服務器單獨運行。若是使用 Unix 系統,須要在 PHP 腳本的最前面加上一行特殊的代碼,使得它可以被執行,這樣系統就能知道用哪一個程序去運行該腳本。在 Windows 平臺下能夠將 php.exe 和 .php 文件的雙擊屬性相關聯,也能夠編寫一個批處理文件來用 PHP 執行腳本。爲 Unix 系統增長的第一行代碼不會影響該腳本在 Windows 下的運行,所以也能夠用該方法編寫跨平臺的腳本程序。如下是一個簡單的 PHP 命令行程序的範例。
Example #1 試圖以命令行方式運行的 PHP 腳本(script.php)
#!/usr/bin/php <?php if ($argc != 2 || in_array($argv[1], array('--help', '-help', '-h', '-?'))) { ?> This is a command line PHP script with one option. Usage: <?php echo $argv[0]; ?> <option> <option> can be some word you would like to print out. With the --help, -help, -h, or -? options, you can get this help. <?php } else { echo $argv[1]; } ?>
在以上腳本中,用第一行特殊的代碼來指明該文件應該由 PHP 來執行。在這裏使用 CLI 的版本,所以不會有 HTTP 頭信息輸出。在用 PHP 編寫命令行應用程序時,可使用兩個參數:$argc 和 $argv。前面一個的值是比參數個數大 1 的整數(運行的腳本自己的名稱也被看成一個參數)。第二個是包含有參數的數組,其第一個元素爲腳本的名稱,下標爲數字 0($argv[0])。
以上程序中檢查了參數的個數是大於 1 個仍是小於 1 個。此外若是參數是 --help ,-help ,-h 或 -? 時,打印出幫助信息,並同時動態輸出腳本的名稱。若是還收到了其它參數,將其顯示出來。
若是但願在 Unix 下運行以上腳本,須要使其屬性爲可執行文件,而後簡單的運行 script.php echothis 或 script.php -h。在 Windows 下,能夠爲此編寫一個批處理文件:
Example #2 運行 PHP 命令行腳本的批處理文件(script.bat)
@C:\php\php.exe script.php %1 %2 %3 %
假設將上述程序命名爲 script.php,且 CLI 版的 php.exe 文件放置在 c:\php\cli\php.exe,該批處理文件會幫助將附加的參數傳給腳本程序:script.bat echothis 或 script.bat -h。