# 控制臺命令
[TOC]
## 創建一個命令
> 命令通過類來定義,一個合法的命令類,沒有固定的目錄和命名空間要求,但必須繼承 `think\console\command\Command` 或者其子類,并且定義 `configure` 和 `execute` 兩個方法。
例如,一個名為 CreateUser 的命令必須遵循此結構:
```php
<?php
// src/application/console/CreateUser.php
namespace app\console;
use think\console\Command;
use think\console\Input;
use think\console\Output;
class CreateUser extends Command
{
protected function configure()
{
// ...
}
protected function execute(Input $input, Output $output)
{
// ...
}
}
```
## 配置命令
> 首先,你必須在 `configure()` 方法中配置命令的名稱,然后可選地定義一個幫助信息 和 輸入選項及輸入參數:
```php
<?php
// src/application/console/CreateUser.php
namespace app\console;
use think\console\Command;
use think\console\Input;
use think\console\Output;
class CreateUser extends Command
{
// ...
protected function configure()
{
$this
// 命令的名字("think" 后面的部分)
->setName('app:create-user')
// 運行 "php think list" 時的簡短描述
->setDescription('Create new users.')
// 運行命令時使用 "--help" 選項時的完整命令描述
->setHelp("This command allows you to create users...")
;
}
protected function execute(Input $input, Output $output)
{
}
}
```
## 執行命令
配置命令之后,然后在 `application` 目錄下面的 `command.php`(如果不存在則創建)文件中添加如下內容:
```php
<?php
return [
\app\console\CreateUser::class,
];
```
你就能在終端(terminal)中執行它:
```bash
$ php think app:create-user
```
你可能已經知道,這個命令將什么也不做,因為你還沒有寫入任何邏輯。在 `execute()` 方法里添加你自己的邏輯,這個方法可以訪問到 `input stream`(如,選項和參數)和 `output stream`(以寫入信息到命令行):
```php
<?php
// src/application/console/CreateUser.php
namespace app\console;
use think\console\Command;
use think\console\Input;
use think\console\Output;
class CreateUser extends Command
{
// ...
protected function configure()
{
$this
// 命令的名字("think" 后面的部分)
->setName('app:create-user')
// 運行 "php think list" 時的簡短描述
->setDescription('Creates new users.')
// 運行命令時使用 "--help" 選項時的完整命令描述
->setHelp("This command allows you to create users...")
;
}
protected function execute(Input $input, Output $output)
{
// 輸出多行到控制臺(每一行的末尾添加 "\n")
$output->writeln([
'Create User',
'============',
'',
]);
// 輸出消息后面跟著一個 "\n"
$output->writeln('Whose!');
// 輸出消息但并不在行的結尾加上 "\n"。
$output->write('You are about to ');
$output->write('create a user.');
}
}
```
現在,嘗試執行此命令:
```bash
$ php think app:create-user
User Creator
============
Whoa!
You are about to create a user.
```
## 控制臺輸入
使用 `input` 選項或參數來傳入信息給命令:
```php
<?php
namespace app\console;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;
class CreateUser extends Command
{
// ...
protected function configure()
{
$this
// 命令的名字("think" 后面的部分)
->setName('app:create-user')
// 配置一個參數
->addArgument('username', Argument::REQUIRED, 'The username of the user.')
// 運行 "php think list" 時的簡短描述
->setDescription('Creates new users.')
// 運行命令時使用 "--help" 選項時的完整命令描述
->setHelp("This command allows you to create users...");
}
protected function execute(Input $input, Output $output)
{
// 輸出多行到控制臺(每一行的末尾添加 "\n")
$output->writeln([
'Create User',
'============',
'',
]);
// 使用 getArgument() 取出參數值
$output->writeln('Username: ' . $input->getArgument('username'));
}
}
```
現在,你可以傳入用戶名到命令中:
```bash
$ php think app:create-user hellokitty
Create User
============
Username: hellokitty
```
## 命令的生命周期
命令有三個生命周期方法可以在運行命令時使用:
`initialize()` (可選)
> 此方法在 `interact()` 和 `execute()` 方法之前執行。它的主要作用是初始化那些用在命令其余方法中的變量。
`interact()` (可選)
> 此方法在 `initialize()` 之后、 `execute()` 之前執行。它的作用是檢查是否錯失了某些選項/參數,然后以互動方式向用戶請求這些值。這是你可以問詢錯失的選項/參數的最后一個地方。此后,丟失的選項/參數將導致一個錯誤。
`execute()` (必須)
> 此方法在 `interact()` 和 `initialize()` 之后執行。它包含你希望命令去執行的邏輯。