## **簡介**
不管是 Node.js、Python 還是 PHP 的 Web 框架,都提供了通過命令行與應用進行交互的功能,通過這些命令行工具,我們可以完成一些初始化操作,比如創建新應用、執行數據庫遷移、或者快速創建類文件等,在 Laravel 中,我們可以通過三種工具實現命令行交互:
* Artisan:Laravel 內置的命令行操作工具集,支持自定義命令;
* Tinker:一個由[PsySH](https://github.com/bobthecow/psysh)擴展包驅動的 REPL,允許你通過命令行與整個 Laravel 應用進行交互;
* Laravel 安裝器,這個我們在[搭建適用于Mac的輕量級開發環境Valet]([http://www.hmoore.net/sdwang/learning\_laravel/1279573](http://www.hmoore.net/sdwang/learning_laravel/1279573))已經提到過,比較簡單,不再贅述。
## **Artisan命令**
我們在前面的學習中已經多次使用過Artisan命令,比如創建控制器:
~~~
php artisan make:controller PostController
~~~
如果你查看應用根目錄,會看到一個`artisan`文件,這個就是命令行交互的入口文件,就像`public/index.php`是 Web 請求的入口文件一樣。在`artisan`文件中,處理流程會像Web請求一樣:注冊類的自動加載器、初始化容器和異常處理器、獲取用戶輸入(`artisan`之后的部分都是請求參數)、執行處理邏輯、最后發送響應(只不過這一切都是在控制臺中完成)。
> 注:Artisan 底層基于[Symfony Console 組件](https://symfony.com/doc/current/components/console.html),所以,如果你之前使寫過 Symfony Console 命令,會很快熟悉 Artisan 命令的使用。
不同的 Laravel 應用由于安裝了不同的擴展包或編寫了自定義的 Artisan 命令,你可以通過`php artisan list`快速瀏覽該應用支持的所有命令。
### **內置Artisan命令**
Laravel應用默認提供了很多(內置)Artisan命令,現在我們挑幾個最基本的命令來看下:
* `help`:為指定命令提供使用幫助信息,如`php artisan help make:request`
* `clear-compiled`:移除編譯過的類文件,比如緩存、Blade視圖文件等
* `down`:將應用切換到維護模式以便查找問題
* `up`:將應用從維護模式恢復為正常模式
* `env`:顯示應用當前運行環境,如`local`、`production`
* `migrate`:運行所有數據庫遷移
* `optimize`:優化應用以便提供更好的性能
* `serve`:在本地`localhost:8000`端口啟動 PHP 內置服務器
* `tinker`:進入 Tinker REPL
* `dump-server`:啟動 dump server 收集`dump`信息
* `preset`:切換應用前端框架腳手架代碼,比如從 Vue 切換到 React
在運行Artisan命令時可以傳入以下選項參數:
* `-q`:禁止所有輸出
* `-v`、`-vv`、`-vvv`:命令執行輸出的三個級別,分別代表正常、詳細、調試
* `--no-interaction`:不會問任何交互問題,所以適用于運行無人值守自動處理命令
* `--env`:允許你指定命令運行的環境
* `--version`:打印當前 Laravel 版本
### **編寫第一個Artisan命令**
在實際項目開發中我們經常需要編寫自定義的Artisan命令,比如數據遷移、數據修復、定時任務等。
首先,我們要了解專門有一個系統自帶命令`make:command`來創建自定義命令文件:
~~~
php artisan make:command WelcomeMessage --command=welcome:message
~~~
該命令的第一個參數就是要創建的 Artisan 命令類名,還可以傳遞一個選項參數`--command`用于自定義該命令的名稱(不指定的話會系統會根據類名自動生成)。執行完該命令后,會在`app/Console/Commands`目錄下創建一個`WelcomeMessage.php`文件:
~~~
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class WelcomeMessage extends Command
{
/**
* 命令名稱,在控制臺執行命令時用到
*
* @var string
*/
protected $signature = 'welcome:message';
/**
* 命令描述
*
* @var string
*/
protected $description = 'print welcome message';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* 命令具體執行邏輯放在這里
*
* @return mixed
*/
public function handle()
{
//我們先簡單打印一條歡迎信息
$this->info('歡迎訪問 Laravel 學院!');
}
}
~~~
然后,創建完 Artisan 命令類后,還需要在`app/Console/Kernel.php`中注冊才能使用,就像編寫好控制器方法后,需要在路由文件中定義路由指向它一樣。
打開`app/Console/Kernel.php`,將新創建的命令類`WelcomeMessage`添加到`$commands`完成注冊:
~~~
protected $commands = [
App\Console\Commands\WelcomeMessage::class
];
~~~
現在,運行`php artisan list`就可以看到`welcome:message`命令了。最后,在應用根目錄下運行`php artisan welcome:message`的話就可以打印上面那條歡迎信息了。
### **基于閉包實現Artisan命令**
當然,就像我們可以在`routes/web.php`中基于閉包實現簡單業務邏輯一樣,對于這么簡單的命令,我們也可以在`routes/console.php`中基于閉包實現:
~~~
Artisan::command('welcome:message_simple', function () {
$this->info('歡迎訪問 Laravel 學院!');
})->describe('打印歡迎信息');
~~~
這樣我們就可以在命令行運行`php artisan welcome:message_simple`打印歡迎信息了,效果和上面通過命令類實現的一樣。
## **通過Tinker實現Laravel命令行交互式Shell**
Laravel Tinker是基于[PsySH](https://github.com/bobthecow/psysh)(通過`composer g require psy/psysh:@stable`全局安裝)——相較于原生的`php -a`,PsySH擁有更多高級特性,比如編寫各種代碼、打印語句、計算表達式、編寫函數等等——實現的,與主要用于編寫和執行Artisan命令不同,通過Tinker我們可以在命令行中實現與Laravel應用的各種交互,包括數據庫的增刪改查。
### **Laravel Tinker使用**
在命令行中通過`php artisan tinker`即可進入 Laravel Tinker 的交互式 Shell。每次我們運行`php artisan tinker`就相當于從控制臺啟動了 Laravel 應用,在運行交互式命令前,`tinker`命令會添加一些命令到Shell,這些命令定義在`Laravel\Tinker\Console\TinkerCommand`的`$commandWhitelist`屬性中:
~~~
protected $commandWhitelist = [
'clear-compiled', 'down', 'env', 'inspire', 'migrate', 'optimize', 'up',
];
~~~
因此,你可以在 Tinker Shell 中直接運行這些命令。
**Tinker最有用的功能,就是可以在Tinker Shell中演練測試 Laravel 代碼**,比如模型和服務。你可以使用控制臺來創建一個新的模型,將其保存到數據庫,然后查詢這條記錄(如果之前沒有運行過`php artisan migrate`命令創建`users`表,先運行`migrate`命令創建):

這里,我們只是介紹了一些入門級的使用示例,更多好玩的東西有賴于你自己在日常開發中去探索,PsySH[官方文檔](http://psysh.org/)有很多資源讓你了解 Tinker 的底層,如果你想了解更多關于 Tinker 的內容,可以去 Tinker 的[GitHub 倉庫](https://github.com/laravel/tinker)逛逛。