PHP 並非廣受關注的命令行腳本語言,但這很可惜,因為 PHP 擁有許多使其成為編寫終端應用程序的理想選擇的特性。
本系列文章將介紹如何使用 Macrame 庫編寫交互式命令行腳本。我們將逐步完成一個示例項目,該腳本從頭到尾獲取Mastodon 用戶關注者列表,並涵蓋以下主題:獲取和驗證用戶輸入、構建交互式菜單、處理命令行參數、安全訪問文件、設置輸出文本樣式以及在向用戶顯示動畫加載器時在後台運行函數。
有關 Macrame 的更多信息,請訪問文檔站點。
我們將要完成的項目是一個簡單的命令行腳本,用於返回 Mastodon 用戶的關注者列表。運行該腳本如下所示:
用戶從動態菜單中選擇所需的 Mastodon 實例,輸入用戶名作為自由文本,腳本在獲取數據時顯示動畫加載器。輸出是一個漂亮的 ASCII 風格表格。
對於想要跳過此步驟的任何人,此項目的完整源代碼都以 gist 的形式提供。
在本部分中,我們將介紹如何:
通過 Composer 安裝 Macrame:
<code class="language-bash">composer require gbhorwood/macrame</code>
安裝 Macrame 後,我們可以設置一個基本的“Hello World”腳本並將其用作我們的起始樣板。雖然從技術上講,此框架並非必需,但使用它會使我們的腳本更安全、更符合規範。讓我們來看一下代碼:
<code class="language-php">#!/usr/bin/env php <?php require __DIR__ . '/vendor/autoload.php'; use Gbhorwood\Macrame\Macrame; // 实例化 Macrame 对象。 // 参数是 ps(1) 所见的脚本名称 $macrame = new Macrame("示例 Macrame 脚本"); // 强制仅在命令行上执行脚本时才运行脚本 if ($macrame->running()) { // 验证主机系统是否可以运行 Macrame 脚本。失败时退出 $macrame->preflight(); // 将文本输出到 STDOUT $macrame->text("Hello World")->write(); // 清洁退出 $macrame->exit(); }</code>
雖然代碼行不多,但這裡發生了很多事情。讓我們來仔細看看。
<code class="language-php">#!/usr/bin/env php</code>
這一行是“shebang”。基本上,它告訴我們的類 Linux 操作系統使用哪個解釋器來運行此腳本。這允許我們運行腳本而無需先鍵入 php。 shebang 必須是文件的第一行,甚至在
<code class="language-php">$macrame = new Macrame("示例 Macrame 脚本");</code>
在這裡,我們創建了一個 Macrame 對象,我們將在腳本的其餘部分使用它。非常標準的內容。唯一有趣的部分是參數。這是操作系統將賦予我們腳本的名稱。例如,如果我們運行 ps 以顯示正在運行的進程列表,我們的腳本將顯示此名稱。
<code class="language-php">if ($macrame->running())</code>
此語句確保塊內的所有代碼僅在命令行上運行腳本時才執行。
<code class="language-bash">composer require gbhorwood/macrame</code>
當我們為命令行編寫 PHP 時,我們對環境的控制不如我們擁有和管理的 Web 服務器那樣多。此處的 preflight() 調用測試本地 PHP 環境,如果它不滿足最低要求,則會終止腳本並顯示錯誤消息。最低要求是:
注意:雖然Macrame 在PHP 7.4 和8.0 上運行,但由於PHP 在8.1 中處理多字節字符串的方式發生了變化,因此在PHP 8.1 之前的版本中,包含表情符號的字符串在輸出中可能無法正確對齊。
<code class="language-php">#!/usr/bin/env php <?php require __DIR__ . '/vendor/autoload.php'; use Gbhorwood\Macrame\Macrame; // 实例化 Macrame 对象。 // 参数是 ps(1) 所见的脚本名称 $macrame = new Macrame("示例 Macrame 脚本"); // 强制仅在命令行上执行脚本时才运行脚本 if ($macrame->running()) { // 验证主机系统是否可以运行 Macrame 脚本。失败时退出 $macrame->preflight(); // 将文本输出到 STDOUT $macrame->text("Hello World")->write(); // 清洁退出 $macrame->exit(); }</code>
這會乾淨地退出腳本,返回 0 的成功代碼。此外,執行期間創建的任何臨時文件都將自動刪除。最好使用 Macrame 的 exit() 函數而不是 PHP 的 die();
編寫完基本的“Hello World”腳本後,我們可以設置其權限以允許執行並在命令行上運行它。
<code class="language-php">#!/usr/bin/env php</code>
Macrame 提供了一套用於解析和讀取命令行參數的工具。讓我們從一些簡單的事情開始:在使用以下命令調用腳本時獲取版本號:
<code class="language-php">$macrame = new Macrame("示例 Macrame 脚本");</code>
對於這種情況,我們只需要檢查這些參數是否存在即可。
我們可以通過調用 Macrame 對像上的 args() 方法來實現此目的,該方法返回一個包含所有腳本參數和我們可以用來檢查它們的眾多方法的對象。要測試參數是否存在,我們可以使用 exists() 方法,如下所示:
<code class="language-php">if ($macrame->running())</code>
exists() 方法返回布爾值。
? Macrame 調用旨在進行鍊式調用。
命令行參數也可用於為變量賦值。例如,要設置用戶名值,我們可能希望用戶能夠像這樣調用腳本:
<code class="language-php">$macrame->preflight();</code>
要在我們的腳本中獲取此參數的值,我們可以使用 args() 提供的 first() 方法,如下所示:
<code class="language-php">$macrame->exit();</code>
顧名思義,first() 方法返回參數的第一個出現的值。如果我們像這樣調用腳本:
<code class="language-bash">chmod 755 ./examplescript.php ./examplescript.php</code>
那麼 first() 將返回“firstuser”值。如果我們想要最後一個值,我們可以調用 last()。如果我們想要所有值作為數組,我們將使用 all()。
將所有這些放在一起,我們的腳本現在看起來像這樣:
<code class="language-bash">./examplescript.php --version # 或 ./examplescript.php -v</code>
處理命令行參數的完整方法列表在 Macrame 參數文檔中有所介紹。
我們還希望允許用戶以交互方式使用我們的腳本。如果他們沒有在命令行上傳遞參數,我們將提示他們輸入數據。對於 Mastodon 實例值,我們將使用菜單。
Macrame 菜單是動態的;用戶可以使用箭頭鍵上下移動列表,然後按
讓我們編寫一個向用戶顯示菜單並返回所選值的函數:
<code class="language-bash">composer require gbhorwood/macrame</code>
此處的核心功能是對以下內容的調用:
<code class="language-php">#!/usr/bin/env php <?php require __DIR__ . '/vendor/autoload.php'; use Gbhorwood\Macrame\Macrame; // 实例化 Macrame 对象。 // 参数是 ps(1) 所见的脚本名称 $macrame = new Macrame("示例 Macrame 脚本"); // 强制仅在命令行上执行脚本时才运行脚本 if ($macrame->running()) { // 验证主机系统是否可以运行 Macrame 脚本。失败时退出 $macrame->preflight(); // 将文本输出到 STDOUT $macrame->text("Hello World")->write(); // 清洁退出 $macrame->exit(); }</code>
我們提供一個字符串數組作為菜單選項,以及一個可選的菜單標題文本,用於 menu()->interactive(),菜單會自動顯示給用戶。用戶的選擇將作為字符串返回。
通過向我們的鏈中添加對 erase() 的調用,還可以選擇在用戶做出選擇後從屏幕上擦除菜單。此方法是可選的,但確實可以保持整潔。
獲得菜單函數後,我們可以修改獲取 Mastodon 實例的方式。我們將嘗試從命令行參數中讀取它,如果未傳遞任何值,則調用我們的 menuInstance() 函數。
<code class="language-php">#!/usr/bin/env php</code>
默認情況下,Macrame 使用終端的默認樣式和顏色來顯示菜單,並將突出顯示的項目設置為反向顯示。如果需要,我們可以通過向我們的鏈中添加一些額外的函數來更改此設置。例如,如果我們更希望突出顯示的項目顯示為粗體紅色文本,我們可以這樣寫:
<code class="language-php">$macrame = new Macrame("示例 Macrame 脚本");</code>
菜單文檔頁面上完整概述了可用於自定義菜單的顏色、樣式和對齊方式的所有方法。
接下來,我們將修改獲取用戶名的方式,使其也接受交互式輸入。在這種情況下,我們將使用 input()->readline() 讀取用戶輸入文本字符串。以下是該函數:
<code class="language-php">if ($macrame->running())</code>
此函數的最後一行是我們輪詢用戶輸入的地方。 readline() 方法接受可選的 $prompt 參數;我們顯示給用戶的文本告訴他們應該輸入什麼。返回值是用戶輸入的字符串。
用戶會犯錯。這就是為什麼輸入驗證很重要。
Macrame 附帶了許多預設方法來驗證輸入。我們可以將任意數量的驗證器添加到我們的鏈中,如果任何驗證器失敗,系統將提示用戶再次輸入。 input()->readline() 函數只有在所有驗證器都通過後才會返回值。
讓我們來看一個例子:
<code class="language-php">$macrame->preflight();</code>
在這裡,我們應用了兩個驗證測試:文本必須為四個或更多個字符,並且不能包含“@”符號。對於這兩種驗證方法,第二個參數是如果驗證失敗我們將向用戶顯示的錯誤消息。
Macrame 輸入文檔頁面上提供了所有預構建驗證函數的完整列表。如果我們想編寫自己的自定義驗證器,那也在其中有所介紹。
如果我們的用戶輸入的是敏感數據,例如密碼,我們可能不希望將他們的按鍵回顯到終端,以免被窺探者看到。
為了解決這個問題,Macrame 提供了 readline() 的“點狀回顯”版本,稱為 readPassword()。
<code class="language-php">$macrame->exit();</code>
readPassword() 讀取的每個按鍵都會以星號的形式回顯。
在如何讀取一行用戶文本的示例中,我們看到了大量用於設置提示文本樣式的代碼。讓我們更詳細地研究一下。
Macrame 允許使用 ANSI 代碼設置終端文本輸出樣式,這使我們可以將粗體和斜體等樣式以及顏色應用於我們的文本。
我們可以通過兩種方式之一在我們的腳本中執行此操作。有一些方法,例如 style() 和 colour()(或 color()),或者我們可以使用基本的文本標記系統。
讓我們首先看看方法方法。
<code class="language-bash">composer require gbhorwood/macrame</code>
在這裡,我們使用 Macrame 的 text() 方法創建了一個“text”對象,然後應用樣式和顏色,最後使用 get() 將其作為字符串返回。
請注意,樣式和顏色方法應用於字符串中的所有文本。如果我們想要將樣式化和著色的文本與純文本混合,我們將不得不創建許多子字符串並將它們連接在一起。這可能會很麻煩,尤其是在處理大量文本時。
或者,我們可以使用 Macrame 的標記系統來簡化文本樣式設置。這是一個示例:
<code class="language-php">#!/usr/bin/env php <?php require __DIR__ . '/vendor/autoload.php'; use Gbhorwood\Macrame\Macrame; // 实例化 Macrame 对象。 // 参数是 ps(1) 所见的脚本名称 $macrame = new Macrame("示例 Macrame 脚本"); // 强制仅在命令行上执行脚本时才运行脚本 if ($macrame->running()) { // 验证主机系统是否可以运行 Macrame 脚本。失败时退出 $macrame->preflight(); // 将文本输出到 STDOUT $macrame->text("Hello World")->write(); // 清洁退出 $macrame->exit(); }</code>
在
需要注意的一點是,標記會關閉所有之前的標記。這是由於 ANSI 轉義碼的行為所致。
這意味著嵌套標記不會像我們預期的那樣工作。例如,在此示例中,第一個標記會關閉
<code class="language-php">#!/usr/bin/env php</code>
到目前為止,我們的示例腳本如下所示:
<code class="language-php">$macrame = new Macrame("示例 Macrame 脚本");</code>
到目前為止,我們已經介紹了讀取命令行參數、從菜單和文本中獲取用戶輸入以及對輸出進行一些基本的文本樣式設置。在下一篇文章中,我們將介紹:
? 本文最初發表在 Grant Horwood 技術博客中
以上是PHP:使用MACRAME編寫命令行應用程序。 Pt 1的詳細內容。更多資訊請關注PHP中文網其他相關文章!