1. 程式人生 > >PHP 命令列

PHP 命令列

PHP 命令列

PHP 從 4.3.0 版本開始給我們提供了 CLI(Command Line Interface) ,即命令列介面。

1 快速上手

假如有如下程式碼:

<?php

echo "My name's fingerQin!\n";

將其儲存任意檔名的檔案。我們這裡是 test.php。

執行該指令碼:

[[email protected] ~]# clear
[[email protected] ~]# php test.php 
My name's fingerQin!

我這裡是在 Linux 環境下的命令列終端執行該指令碼。

注意:

1)首要確定你已經在系統當中安裝了 PHP 並且已經將 PHP 命令設定到了系統環境變數當中。

2)Window 系統下請用命令列提示符工具來執行。

2 CLI 與 CGI 的區別

CLI 是 PHP 專門提供給我們與命令列互動的工具。CGI 是 PHP 提供給 Web Server 通訊的介面。所以,在我們的 PHP 專案開發當中,很多框架都會提供一個 Web 模式的入口,一個 CLI 的入口。

  • 與 CGI 不同,CLI 其輸出沒有任何頭(Header)資訊。
  • CLI 模式下,出錯時輸出純文字的錯誤資訊(非 HTML 格式)。
  • CLI 模式下,所有來自 print 和 echo 的輸出將被立即寫到輸出端。而不作任何緩衝操作。
  • CLI 模式下,最大執行時間(max_execution_time)被設定為無限值。
  • CLI 模式下,$argc$argv 兩個變數總是存在。並且攜帶了引數個數與實際的引數陣列值。
  • CLI SAPI 不會將當前目錄改為已執行的指令碼所在的目錄。
  • CLI 模式提供了幾個專用常量:STDIN、STDOUT、STDERR。

注意:配置檔案(php.ini)當中 html_errors、implicit_flush、max_execution_time、register_argc_argv 對其修改對 CLI 模式下執行的 PHP 來說沒有任意作用。因為,CLI 啟動的時候會重置這些值。

接下來我們對它們的這些區別進行分開說明。

2.1)CLI 模式沒有任何頭(Header)資訊。

因其 CLI 是命令列下互動的介面。Header 頭是 HTTP 協議定義的一部分。在 CGI 模式才支援這些互動協議。所以,Header 頭資訊對 CLI 模式來說並沒有任何意義。所以,CLI 模式不會有任何頭資訊。PHP 也沒有提供相應的配置來開啟支援頭資訊的輸出。

2.2)CLI 模式常用的輸出會立即寫到輸出端,而不作任何緩衝操作。

在 CGI 模式下,因其要考慮到效能以及通訊的問題。所以,伺服器端的輸出是一次性執行結束輸出到客戶端。但是, CLI 模式下通常不會有這種的需求。

如果希望延緩或控制標準輸出,仍然可以使用 output buffering 設定項改變其行為。

驗證:

<?php

echo "My name's fingerQin!\n";
sleep(3);
echo "ok\n";

假如有如上 PHP 程式碼,在 CLI 模式下,我們會發現會立即輸出結果。並會不等待 3 秒再輸出。如果是在 CGI 模式下,會等待 3 秒再輸出結果。這就是它們的區別。

注:該區別是受配置檔案 php.ini 中 implicit_flush 控制。在 CLI 模式下此值始終為 TRUE。

2.3)CLI 模式下,出錯時輸出純文字的錯誤資訊(非 HTML 格式)。

PHP 在出錯時,輸出的錯誤資訊預設格式是受 php.ini 中 html_errors 控制。在 CLI 模式下此值始終為 FALSE。因為,無意義的 HTML 標記符會使得出錯資訊很凌亂,所以在外殼下閱讀報錯資訊是十分困難的。

2.4)CLI 模式下,最大執行時間(max_execution_time)被設定為無限值。

因為,通常在 CLI 模式下執行的程式可能出現無窮執行下去的可能性。所以,最大執行時間被設定為了無限值。這個跟 WEB 開發下應用程式可能只需要幾秒鐘。

PHP 配置檔案當中 max_execution_time 在 CLI 模式下始終為 0。即執行時間無限制。

2.5)CLI 模式下,$argc$argv 兩個變數總是存在。並且攜帶了引數個數與實際的引數陣列值。

這兩個值是 CLI 模式下專屬的值。在 CLI 啟動的時候這兩個變數就已經被初始化。$argc 儲存的是當前命令列的引數個數,$argv 儲存的是命令的引數值,且型別為陣列。

所以,在 CLI 開發時,不要對這兩個變數進行任何的寫操作。除非你明確知道自己這樣做的後果。

2.6)CLI SAPI 不會將當前目錄改為已執行的指令碼所在的目錄。**

這個怎麼理解呢?比如,我們在為 /home 的目錄下,用 PHP 命令執行了某個 PHP 指令碼。但是,此時通過 getcwd() 得到的結果不是 /home 而是指令碼所在的目錄。

總之,我們只要記住當前目錄始終為指令碼所在目錄即可。

2.7)CLI 模式提供了幾個專用常量:STDIN、STDOUT、STDERR。

有了以上常量,就無需自己建立指向諸如 stderr 的流,只需簡單的使用這些常量來代替流指向:

php -r 'fwrite(STDERR, "stderr\n");'

3 執行 PHP 程式碼的三種方式

CLI SAPI 模組有以下三種不同的方法來獲取要執行的 PHP 程式碼:

3.1)讓 PHP 執行指定檔案

php my_script.php

php -f my_script.php

以上兩種方法(使用或不使用 -f 引數)都能夠執行給定的 my_script.php 檔案。可以選擇任何檔案來執行,指定的 PHP 指令碼並非必須要以 .php為副檔名,它們可以有任意的檔名和副檔名。

3.2)在命令列直接執行 PHP 程式碼

php -r 'print_r(get_defined_constants());'

在使用這種方法時,請注意外殼變數的替代及引號的使用。

請仔細閱讀以上範例,在執行程式碼時沒有開始和結束的標記符!加上 -r 引數後,這些標記符是不需要的,加上它們會導致語法錯誤。

3.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 解析完引數後,該符號後所有的引數將會被原樣傳送給指令碼程式。

4 PHP 命令引數說明

引數 長名稱 說明
-a --interactive 互動式執行 PHP。如果編譯 PHP 時加入了 Readline 擴充套件(Windows 下不可用),那將會得到一個很好的外殼,包括一個自動完成的功能(例如可以在鍵入變數名的時候,按下 TAB 鍵,PHP 會自動完成該變數名)以及命令歷史記錄,可以用上下鍵來訪問。歷史記錄存在 ~/.php_history 檔案中。
-c --php-ini 用該引數,可以指定一個放置 php.ini 檔案的目錄,或者直接指定一個自定義的 INI 檔案(其檔名可以不是 php.ini),例如:php -c /custom/directory/ my_script.phpphp -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]
-e --profile-info 啟用擴充套件資訊模式,被用於除錯/測試。
-f --file 解析並執行 -f 選項給定的檔名。該引數為可選引數,可以省略,僅指明需要執行的檔名即可。
-i --info 該命令列引數會呼叫 phpinfo() 函式並顯示出結果。如果 PHP 沒有正常工作,建議執行 php -i 命令來檢視在資訊表格之前或者對應的地方是否有任何錯誤資訊輸出。請注意當使用 CGI 摸索時,輸出的內容為 HTML 格式,因此輸出的資訊篇幅較大。
-l --syntax-check 該引數提供了對指定 PHP 程式碼進行語法檢查的方便的方法。如果成功,則向標準輸出寫入 No syntax errors detected in <filename> 字串,並且外殼返回值為 0。如果失敗,則輸出 Errors parsing <filename> 以及內部解析器錯誤資訊到標準輸出,同時外殼返回值將別設定為 255。 <br />該引數將無法檢查致命錯誤(如未定義函式),如果也希望檢測致命錯誤,請使用 -f 引數。 該引數不能和 -r 一同使用。
-m --modules 使用該引數,PHP 將打印出內建以及已載入的 PHP 及 Zend 模組。
-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 新加。
-s --syntax-highlight 顯示有語法高亮色彩的原始碼。 感覺沒啥用。
-v --version 將 PHP,PHP SAPI 和 Zend 的版本資訊寫入標準輸出。
-w --strip 顯示除去了註釋和多餘空白的原始碼。
-z --zend-extension 載入 Zend 擴充套件庫。如果僅給定一個檔名,PHP 將試圖從當前系統擴充套件庫的預設路徑(在 Linux 系統下,該路徑通常由 /etc/ld.so.conf 指定)載入該擴充套件庫。如果用一個絕對路徑指定檔名,則不會使用系統的擴充套件庫預設路徑。如果用相對路徑指定的檔名,則 PHP 僅試圖在當前目錄的相對目錄載入擴充套件庫。
--ini   顯示配置檔名稱。
--rf   顯示指定方法相關資訊。對語言結構無效。echo、print 等語言結構不可以。
--rc   顯示指定類相關資訊。
--re   顯示指定擴充套件相關資訊。
--rz   顯示指定 Zend 擴充套件相關資訊。
--ri   顯示指定擴充套件的配置資訊。

5 實際應用案例

5.1)檢視 PHP 版本

[[email protected] test]# php -v
PHP 7.1.12 (cli) (built: Nov 29 2017 11:18:30) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.1.12, Copyright (c) 1999-2017, by Zend Technologies
    with Xdebug v2.6.0, Copyright (c) 2002-2018, by Derick Rethans

5.2)檢視 PHP 擴充套件列表

[[email protected] test]# php -m
[PHP Modules]
bcmath
Core
ctype
curl
date
dom
event
exif
fileinfo
filter
ftp
gd
......

通過這種方式,我們就知道了 PHP 已經安裝啟用了哪些擴充套件。

5.3)檢視指定配置資訊

假如,我們現在想快速檢視 session 相關的配置資訊。可通過如下方式操作:

[[email protected] test]# php -i|grep session
session
session.auto_start => Off => Off
session.cache_expire => 180 => 180
session.cache_limiter => nocache => nocache
session.cookie_domain => no value => no value
session.cookie_httponly => Off => Off
session.cookie_lifetime => 0 => 0
session.cookie_path => / => /
session.cookie_secure => Off => Off
session.gc_divisor => 1000 => 1000
session.gc_maxlifetime => 1440 => 1440
session.gc_probability => 1 => 1
session.lazy_write => On => On
session.name => PHPSESSID => PHPSESSID
session.referer_check => no value => no value
session.save_handler => files => files
session.save_path => no value => no value
session.serialize_handler => php => php
session.sid_bits_per_character => 5 => 5
session.sid_length => 26 => 26
session.upload_progress.cleanup => On => On
session.upload_progress.enabled => On => On
session.upload_progress.freq => 1% => 1%
session.upload_progress.min_freq => 1 => 1
session.upload_progress.name => PHP_SESSION_UPLOAD_PROGRESS => PHP_SESSION_UPLOAD_PROGRESS
session.upload_progress.prefix => upload_progress_ => upload_progress_
session.use_cookies => On => On
session.use_only_cookies => On => On
session.use_strict_mode => Off => Off
session.use_trans_sid => 0 => 0
session.trans_sid_hosts => no value => no value
session.trans_sid_tags => a=href,area=href,frame=src,form= => a=href,area=href,frame=src,form=

5.4)驗證 PHP 指令碼是否存在語法錯誤

這個功能通常用於一些 PHP IDE 整合開發工具,它們用來檢查當前 PHP 指令碼是否存在語法錯誤。另外,有些 PHP 開發者在 Linux 命令列工作的時候,想快速檢查自己編寫的程式碼是否存在語法錯誤。

[[email protected] test]# php -l test.php 
No syntax errors detected in test.php

但是,我在使用的時候,發現連 notice 級別的錯誤都檢查不出來。不知道是不是姿勢不對?還是這個命令還不夠成熟。

5.5)檢視 PHP 使用的配置檔案

有時候,我們不知道 PHP 載入的 PHP 檔案的位置。可以通過如下命令快速獲悉:

[[email protected] test]# php --ini
Configuration File (php.ini) Path: /usr/local/php71/etc
Loaded Configuration File:         /usr/local/php71/etc/php.ini
Scan for additional .ini files in: /usr/local/php71/etc/php.d
Additional .ini files parsed:      (none)

5.6)檢視是否存在內建方法

存在:

[[email protected] test]# php --rf strlen
Function [ <internal:Core> function strlen ] {

  - Parameters [1] {
    Parameter #0 [ <required> $str ]
  }
}

不存在:

[[email protected] test]# php --rf strlens
Exception: Function strlens() does not exist

注意:語言結構通過這種方式是會被認為不存在該方法的。所以,該方法也可以用來判決是否為語言結構。

[[email protected] test]# php --rf echo
Exception: Function echo() does not exist

5.7)檢視是否存在內建類

[[email protected] test]# php --rc PDO
Class [ <internal:PDO> class PDO ] {

  - Constants [86] {
    Constant [ public integer PARAM_BOOL ] { 5 }
    Constant [ public integer PARAM_NULL ] { 0 }
    Constant [ public integer PARAM_INT ] { 1 }
    Constant [ public integer PARAM_STR ] { 2 }
    Constant [ public integer PARAM_LOB ] { 3 }
    Constant [ public integer PARAM_STMT ] { 4 }
    Constant [ public integer PARAM_INPUT_OUTPUT ] { 2147483648 }
    Constant [ public integer PARAM_EVT_ALLOC ] { 0 }
    Constant [ public integer PARAM_EVT_FREE ] { 1 }
    Constant [ public integer PARAM_EVT_EXEC_PRE ] { 2 }
    Constant [ public integer PARAM_EVT_EXEC_POST ] { 3 }
    Constant [ public integer PARAM_EVT_FETCH_PRE ] { 4 }
    ......

當然該命令本身是用來檢視類定義的。

不存在類的情況會如下提示:

[[email protected] test]# php --rc PDO_EXCEPTION
Exception: Class PDO_EXCEPTION does not exist

5.8)檢視擴充套件是否存在

方式一:

[[email protected] test]# php --re yafs
Exception: Extension yafs does not exist

方式二:

[[email protected] test]# php -m|grep yaf
yaf

注:php --re 命令是用來檢視擴充套件定義相關的資訊的。可以自行執行檢視。

5.9)檢視擴充套件配置資訊

[[email protected] test]# php --ri yaf

yaf

yaf support => enabled
Version => 3.0.6
Supports => http://pecl.php.net/package/yaf

Directive => Local Value => Master Value
yaf.library => no value => no value
yaf.action_prefer => Off => Off
yaf.lowcase_path => Off => Off
yaf.use_spl_autoload => Off => Off
yaf.forward_limit => 5 => 5
yaf.name_suffix => On => On
yaf.name_separator => no value => no value
yaf.st_compatible => Off => Off
yaf.environ => product => product
yaf.use_namespace => Off => Off

有時候,我們想知道擴充套件的版本,以及配置資訊。可以通過這種方式快捷獲知。



作者:fingerQin
連結:https://www.jianshu.com/p/c871342a7310
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。