PHP的命令行擴展Readline相關函數(shù)的使用
readline 擴展函數(shù)實現(xiàn)了訪問 GNU Readline 庫的接口。這些函數(shù)提供了可編輯的命令行。一個例子是在 Bash 中允許你使用箭頭按鍵來插入字符或者翻看歷史命令。因為這個庫的交互特性,這個功能在你寫的 Web 程序中沒多大用處,但是當你寫的腳本被用在命令行中時非常有用。
Readline 擴展的安裝
Readline 擴展已經(jīng)加入了 PHP 的官方安裝包中,如果是新的 PHP 環(huán)境,那么在編譯的時候加上 --with-readline 即可。另外,我們還需要安裝操作系統(tǒng)的 Readline 庫。當然,如果已經(jīng)是正常運行的 PHP ,也可以重新編譯一下。
# yum install -y readline-devel # ./congiure xxxx --with-readline
默認情況下,如果沒有在編譯時增加 --whit-readline ,Readline 的一些函數(shù)也是可以使用的,不過它們調(diào)用的是系統(tǒng)的 libedit 庫。有一些函數(shù),比如 readline_list_history() 這種函數(shù)是無法使用的。要想完整的使用 Readline 擴展的能力,那么還是需要安裝操作系統(tǒng)的 libreadline 庫(上面 yum 安裝的那個 readline-devel )并在 PHP 中進行相應參數(shù)的編譯安裝。
基本函數(shù)操作
Readline 擴展提供的函數(shù)不多,也非常的簡單易用。
讀取一行
$line = readline("請輸入命令:"); // 讀取命令行交互信息 echo $line, PHP_EOL; // aaa
運行 PHP 代碼后,我們就進入了命令提示符等待狀態(tài),并且會提示“請輸入命令:”,當我們輸入了 aaa 并回車之后,輸入的內(nèi)容就保存到了 $line 變量中。
命令歷史列表相關操作
Readline 很強大的一個功能就是它自帶一套命令歷史記錄的功能。不過這個需要我們自己手動地將命令加入到命令歷史中。
$line = readline("請輸入命令:"); // 讀取命令行交互信息 if (!empty($line)) { readline_add_history($line); // 需要手動加入到命令歷史記錄中 } echo $line, PHP_EOL; // aaa $line = readline("請輸入命令:"); if (!empty($line)) { readline_add_history($line); } // 命令歷史記錄列表 print_r(readline_list_history()); // Array // ( // [0] => aaa // [1] => bbb // )
使用 readline_add_history() 函數(shù),就可以將一條命令加入到命令歷史記錄中,然后使用 readline_list_history() 就能夠打印出我們之前在交互式環(huán)境中發(fā)送過的命令記錄。當然,如果只是這樣簡單的保存再打印那就沒意思了,它還能將這些歷史信息保存到外部文件進行存儲。
// 將命令歷史記錄寫入到一個文件中 readline_write_history('./readline_history'); // ./readline_history中 // _HiStOrY_V2_ // aaa // bbb // 清理命令歷史記錄 readline_clear_history(); print_r(readline_list_history()); // Array // ( // ) // 從文件中讀取命令歷史記錄 readline_read_history('./readline_history'); print_r(readline_list_history()); // Array // ( // [0] => bbb // [1] => bbb // )
我們使用 readline_write_history() 函數(shù)將當前的命令歷史記錄保存到一個文件中,然后使用 readline_clear_history() 清理掉目前命令歷史記錄列表中的內(nèi)容,這個時候打印 readline_list_history() 的話里面已經(jīng)沒有任何東西了。接著,我們再使用 readline_read_history() 將命令的歷史記錄從文件中加載回來進行還原。這一套功能是不是就非常有意思了,我們可以記錄客戶的所有命令操作,不管是安全審查還是事件回放,都非常有用。
查看 Readline 狀態(tài)
// 當前命令行內(nèi)部的變量信息 print_r(readline_info()); // Array // ( // [line_buffer] => bbb // [point] => 3 // [end] => 3 // [mark] => 0 // [done] => 1 // [pending_input] => 0 // [prompt] => 請輸入命令: // [terminal_name] => xterm-256color // [completion_append_character] => // [completion_suppress_append] => // [library_version] => 7.0 // [readline_name] => other // [attempted_completion_over] => 0 // )
readline_info() 函數(shù)就比較簡單了,我們可以看到最后一條交互式命令的信息,里面包括了命令輸入的內(nèi)容 line_buffer ,內(nèi)容長度 point ,提示信息 prompt 等內(nèi)容。
命令提示效果
在 Linux 等操作系統(tǒng)上,我們想不起一個命令的全拼沒關系,只需要記住它的前幾個字符然后按兩個 Tab 鍵就可以得到相關的命令提示了。Readline 擴展庫當然也為我們準備了這樣的功能。
// 類似于命令行中按 Tab 鍵的提示效果 readline_completion_function(function ($input, $index) { $commands = ['next', 'exit', 'quit']; $matches = []; if ($input) { // 如果關鍵字包含在命令中,提示命令信息 foreach ($commands as $c) { if (strpos($c, $input) !== false) { $matches[] = $c; } } }else{ $matches = $commands; } return $matches; }); // 使用 Tab 鍵測試一下吧 $line = trim(readline("請輸入命令:")); if (!empty($line)) { readline_add_history($line); } echo $line, PHP_EOL; // 當前輸入的命令信息 // 如果命令是 exit 或者 quit ,就退出程序執(zhí)行 if($line == 'exit' || $line == 'quit'){ exit; }
readline_completion_function() 函數(shù)會接收一個回調(diào)函數(shù),當在交互式命令行模式下,也就是 readline 函數(shù)調(diào)用時,按下 Tab 鍵的時候,就會進入到這個函數(shù)的回調(diào)函數(shù)中。\$input 是當前已經(jīng)輸入內(nèi)容的值,$index 是第幾個字符。我們在這個回調(diào)函數(shù)中定義了幾個默認的命令,當你鍵入一個 n 時直接按 Tab 鍵,程序就是提示出完整的 next 命令出來。當然,多個相同的字母開頭的都是可以通過這個 $matches 數(shù)組返回呈現(xiàn)的。
此外,在這段代碼中,如果我們輸入了 exit 或者 quit 。將退出程序的運行。
字符回調(diào)操作相關示例
最后幾個函數(shù)我們將通過一個復雜的小測試來學習。
// 輸出的內(nèi)容進入這個回調(diào)函數(shù)中 function rl_callback($ret) { global $c, $prompting; echo "您輸入的內(nèi)容是: $ret\n"; $c++; readline_add_history($ret); // 限制了就調(diào)用10次,也可以通過命令行輸入的內(nèi)容來判斷,比如上面的 exit 那種進行退出 if ($c > 10) { $prompting = false; // 移除上一個安裝的回調(diào)函數(shù)句柄并且恢復終端設置 readline_callback_handler_remove(); } else { // 繼續(xù)進行遞歸回調(diào) readline_callback_handler_install("[$c] 輸入點什么內(nèi)容: ", 'rl_callback'); } } $c = 1; $prompting = true; // 初始化一個 readline 回調(diào)接口,然后終端輸出提示信息并立即返回,需要等待 readline_callback_read_char() 函數(shù)調(diào)用后才會進入到回調(diào)函數(shù)中 readline_callback_handler_install("[$c] 輸入點什么內(nèi)容: ", 'rl_callback'); // 當 $prompting 為 ture 時,一直等待輸入信息 while ($prompting) { $w = null; $e = null; $r = array(STDIN); $n = stream_select($r, $w, $e, null); if ($n && in_array(STDIN, $r)) { // 當一個行被接收時讀取一個字符并且通知 readline 調(diào)用回調(diào)函數(shù) readline_callback_read_char(); } } echo "結束,完成所有輸入!\n"; // [1] 輸入點什么內(nèi)容: A // 您輸入的內(nèi)容是: A // [2] 輸入點什么內(nèi)容: B // 您輸入的內(nèi)容是: B // [3] 輸入點什么內(nèi)容: C // 您輸入的內(nèi)容是: C // [4] 輸入點什么內(nèi)容: D // 您輸入的內(nèi)容是: D // [5] 輸入點什么內(nèi)容: E // 您輸入的內(nèi)容是: E // [6] 輸入點什么內(nèi)容: F // 您輸入的內(nèi)容是: F // [7] 輸入點什么內(nèi)容: G // 您輸入的內(nèi)容是: G // [8] 輸入點什么內(nèi)容: H // 您輸入的內(nèi)容是: H // [9] 輸入點什么內(nèi)容: I // 您輸入的內(nèi)容是: I // [10] 輸入點什么內(nèi)容: J // 您輸入的內(nèi)容是: J // 結束,完成所有輸入! print_r(readline_list_history()); // Array // ( // [0] => A // [1] => B // [2] => C // [3] => D // [4] => E // [5] => F // [6] => G // [7] => H // [8] => I // [9] => J // )
首先,我們先不管上面的這個自定義的函數(shù),直接向下看到 readline_callback_read_char() 。它的作用是當一個行被接收時讀取一個字符并且通知 readline 調(diào)用回調(diào)函數(shù)。也就是當一行輸入完成后,鍵入了回車之后,這個函數(shù)將通知 Readline 組件去調(diào)用 readline_callback_handler_install() 注冊的回調(diào)函數(shù)。
readline_callback_handler_install() 函數(shù)的功能是初始化一個 readline 回調(diào)接口,然后終端輸出提示信息并立即返回,如果在回調(diào)函數(shù)中不進行什么操作的話,這個函數(shù)就只是輸出一個提示就結束了。在我們例子中的這個回調(diào)函數(shù) rl_callback() 中,我們根據(jù)當前接收命令的次數(shù),判斷如果接收的命令在十次內(nèi),則繼續(xù)接收命令直到十次命令為止就調(diào)用 readline_callback_handler_remove() 移除上一個 readline_callback_handler_install() 安裝的回調(diào)并恢復終端的默認設置。
最后執(zhí)行的結果就是注釋中的內(nèi)容,大家也可以自己復制下代碼后運行調(diào)試,只有自己進行過的調(diào)試才能理解的更加深入。
總結
Readline 很強大,而且也是 PHP 默認安裝包中自帶的擴展。一般被加入默認的擴展都是經(jīng)過時間檢驗而且非常有用的擴展,大家可以根據(jù)這些內(nèi)容再進行更加深入的學習并運用到實戰(zhàn)中。
測試代碼:
https://github.com/zhangyue0503/dev-blog/
以上就是PHP的命令行擴展Readline相關函數(shù)的使用的詳細內(nèi)容,更多關于PHP 命令行擴展Readline的使用的資料請關注腳本之家其它相關文章!
相關文章
php+jQuery實現(xiàn)的三級導航欄下拉菜單顯示效果
這篇文章主要介紹了php+jQuery實現(xiàn)的三級導航欄下拉菜單顯示效果,涉及php數(shù)組遍歷與jQuery事件響應操作頁面元素變換等相關操作技巧,需要的朋友可以參考下2017-08-08PHP使用反向Ajax技術實現(xiàn)在線客服系統(tǒng)詳解
這篇文章主要介紹了PHP使用反向Ajax技術實現(xiàn)在線客服系統(tǒng),簡單描述了反向ajax的概念、原理及使用反向ajax實現(xiàn)在線客服的相關操作技巧,需要的朋友可以參考下2019-07-07非常好用的兩個PHP函數(shù) serialize()和unserialize()
使用serialize()函數(shù)和unserialize()函數(shù),這兩個函數(shù)的用法真是絕配,一個是進行序列化存儲,另一個則是進行序列化恢復,方便極了2012-02-02PHP IDE PHPStorm配置支持友好Laravel代碼提示方法
這篇文章主要介紹了PHP IDE PHPStorm配置支持友好Laravel代碼提示方法,重點配置已經(jīng)加紅提示,需要的朋友可以參考下2015-05-05PHP基于DateTime類解決Unix時間戳與日期互轉問題【針對1970年前及2038年后時間戳】
這篇文章主要介紹了PHP基于DateTime類解決Unix時間戳與日期互轉問題,通過DateTime類解決1970年前及2038年后時間戳顯示與計算問題,非常簡單實用,代碼中備有較為詳盡的注釋便于理解,需要的朋友可以參考下2018-06-06php_imagick實現(xiàn)圖片剪切、旋轉、銳化、減色或增加特效的方法
這篇文章主要介紹了php_imagick實現(xiàn)圖片剪切、旋轉、銳化、減色或增加特效的方法,可實現(xiàn)通過調(diào)用ImageMagick功能的PHP擴展使PHP具備和ImageMagick相同的功能,最終實現(xiàn)強大的ImageMagick圖形處理功能,非常具有實用價值,需要的朋友可以參考下2014-12-12