首頁  >  文章  >  php框架  >  一起聊聊Laravel運行命令列腳本

一起聊聊Laravel運行命令列腳本

WBOY
WBOY轉載
2022-04-06 17:49:562946瀏覽

這篇文章為大家帶來了關於Laravel的相關知識,其中主要介紹了運行命令列腳本的相關問題,Laravel 中有個專門單獨的目錄,也就是Console 目錄,它是用於存放腳本文件的。下面一起來看一下,希望對大家有幫助。

一起聊聊Laravel運行命令列腳本

推薦學習:Laravel入門

#我們看到了Laravel 中有個專門單獨的目錄,也就是Console 目錄,它是用於存放腳本文件的。這個腳本檔案一般指的就是我們透過 php 指令來執行的命令列腳本,在許多框架中都有這樣的功能。對於現代化的應用開發來說,一些資料統計、資料匯出、佇列處理等比較耗時的功能,以及一些自動化的後端執行程序,都需要使用這種命令列腳本來執行。

預設提供的腳本

在目前的框架目錄中,我們在根目錄執行php artisan ,就可以看到命令列的幫助信息,這裡就列出了所有已經存在的命令列腳本。在第一篇文章中,我們就接觸過這其中的兩個指令。

# php artisan key:generate
# php artisan serve

它們的作用一個是產生一個加密快取等需要使用的唯一 Key ,另一個是運行一個自帶的簡易伺服器。從腳本名稱我們可以看出,腳本可以以一個 : 分隔,冒號前面是大的分類,例如有 cache:xxx 相關的,也有 make:xxx 相關的。 cache 相關的就是處理一些快取資訊的,而 make 相關的則是創建一些我們需要的文件,例如創建一個控制器可以使用 make:controller ,創建一個資料模型可以使用 make:model 。

關於這些預設自帶的腳本,我們將在學習到相關內容的時候順帶著一起學習。

自訂一個腳本

自訂一個腳本非常簡單。我們可以使用 make:command 指令來產生一個命令列腳本。

# php artisan make:command test1
Console command created successfully.

這時,在 app/Console/Commands 目錄下就會出現一個 test1.php 檔案。打開這個文件,我們需要做一些修改。

/**
 * The name and signature of the console command.
 *
 * @var string
 */
protected $signature = 'command:name';
/**
 * The console command description.
 *
 * @var string
 */
protected $description = 'Command description';

signature 用來設定目前這個腳本的名稱,description 用來定義腳本的註解說明。它們用在什麼地方呢?其實 signature 就是我們透過 php artisan 來執行這個腳本時所需要用到的名稱。例如我們現在直接執行 php artisan 的話,就會看到下面這樣一條可執行命令列腳本的出現。

 command
  command:name         Command description

當然,使用這個預設的名稱並不是好的主意,所以我們可以修改這兩個屬性。

/**
 * The name and signature of the console command.
 *
 * @var string
 */
protected $signature = 'ZyBlog:Test1';
/**
 * The console command description.
 *
 * @var string
 */
protected $description = '硬核测试1';

這時候我們再執行 php artisan 的話,就可以看到我們定義的資訊了。

 ZyBlog
  ZyBlog:Test1         硬核测试1

如果要執行這個腳本也非常簡單。

# php artisan ZyBlog:Test1

當然,我們還什麼都沒做呢,所以不會有任何輸出。接下來我們把接收參數和輸出訊息一起做了。接收參數需要在 signature 中定義我們要接收的參數及選項。還記得我們之前講過的 PHP 如何接收腳本參數及選項資訊的文章嗎? Laravel 已經將這些封裝好了,不需要再去使用那些函數來進行接收處理,直接使用就可以了。需要複習的同學可以移步 【如何取得PHP命令列參數】mp.weixin.qq.com/s/dFuGaM1JT… 進行複習或學習。

protected $signature = 'ZyBlog:Test1 {a=1} {--b=*}';
/**
 * Execute the console command.
 *
 * @return int
 */
public function handle()
{
    echo "欢迎进来测试!", PHP_EOL;
    print_r($this->arguments());
    // Array
    // (
    //     [command] => ZyBlog:Test1
    //     [a] => 1
    // )
    print_r($this->options());
    // Array
    // (
    //     [b] => Array
    //         (
    //             [0] => 2
    //         )
    
    //     [help] => 
    //     [quiet] => 
    //     [verbose] => 
    //     [version] => 
    //     [ansi] => 
    //     [no-ansi] => 
    //     [no-interaction] => 
    //     [env] => 
    // )
    echo $this->argument('a'); // 1
    print_r($this->option('b'));
    // Array
    // (
    //     [0] => 2
    // )
    return 0;
}

在 handle() 函數中,我們可以寫出目前這個腳本需要執行的函數程式碼。其中,透過 arguments() 和 argument() 可以接收到腳本的參數訊息,透過 options() 和 option() 可以接收到腳本的選項訊息。關於參數和選項的問題,之前的文章中我們也講解過了,這裡也就不多說了,一切都是以基礎為準的。

參數選項原始碼分析

對於參數和選項來說,Laravel 的底層呼叫的其實是symfony 的Console 元件,在symfony/console/Input/ArgvInput.php 中,我們可以看到下面這些程式碼。

public function __construct(array $argv = null, InputDefinition $definition = null)
{
    $argv = $argv ?? $_SERVER['argv'] ?? [];
    // strip the application name
    array_shift($argv);
    $this->tokens = $argv;
    parent::__construct($definition);
}
// ……………………
// ……………………
protected function parse()
{
    $parseOptions = true;
    $this->parsed = $this->tokens;
    while (null !== $token = array_shift($this->parsed)) {
        if ($parseOptions && '' == $token) {
            $this->parseArgument($token);
        } elseif ($parseOptions && '--' == $token) {
            $parseOptions = false;
        } elseif ($parseOptions && 0 === strpos($token, '--')) {
            $this->parseLongOption($token);
        } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {
            $this->parseShortOption($token);
        } else {
            $this->parseArgument($token);
        }
    }
}

很明顯,在 symfony 中,也是使用的 argv 取得參數和選項,然後將它們放到 input 變數中向下傳遞。這個 input 變數很重要,後面我們在學習請求相關的內容時也會接觸到。之後在我們的執行程式碼中,也就是 Command 的 handle() 方法中使用 argument() 或 option() 取得到的就是這個 input 中的資料。從斷點調試中我們就可以看到它們的身影。

一起聊聊Laravel運行命令列腳本

那麼 Laravel 是如何執行 handle() 函數的呢?首先透過artisan 檔案呼叫到laravel/framework/src/Illuminate/Foundation/Console/Kernel.php 文件,在這個Kernel.php 中的handle() 方法中會呼叫symfony/console/Application.php ,接著進入laravel/frameworklaravel/framework /src/Illuminate/Console/Command.php 中執行execute() 方法,透過回呼的方式呼叫我們自訂的那個handle() 方法。

注意,在 laravel/framework/src/Illuminate/Console/Command.php 的底層還是呼叫的 symfony 下面的 console/command.php 裡面的方法。

整個呼叫鏈條非常長,不過也可以清楚看出我們的 Laravel 確實就是在 Symfony 的基礎上又套了層殼。而且不僅僅是命令列這裡,在 Web 請求這一塊,依然底層還是 Symfony 在發揮著至關重要的作用。

推薦學習:Laravel影片教學

#

以上是一起聊聊Laravel運行命令列腳本的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.im。如有侵權,請聯絡admin@php.cn刪除