# 理解控制台参数是如何被操作的
要理解 `console` 程序的参数处理方式是比较困难的。`Think Console`,像很多其他的 `CLI` 工具一样,遵循的是 [docopt](http://docopt.org/) 标准中所描述的行为。
看看下面这个拥有三个选项的命令:
```php
<?php
namespace app\console;
use think\console\Command;
use think\console\Output;
use think\console\Input;
use think\console\input\Option;
use think\console\input\Definition;
class DemoCommand extends Command
{
protected function configure()
{
$this
// 命令的名字("think" 后面的部分)
->setName('demo:args')
->setDescription('Describe args behaviors')
->setDefinition(
new Definition(array(
new Option('foo', 'f'),
new Option('bar', 'b', Option::VALUE_REQUIRED),
new Option('cat', 'c', Option::VALUE_OPTIONAL),
))
);
}
protected function execute(Input $input, Output $output)
{
// ...
}
}
```
由于 `foo` 选项并不接收一个值,它将是 `false`(若它未传入命令)或 `true`(当 `--foo` 被用户传入)。`bar` 选项的值(以及它的 `b` 快捷方式)是必填项。它(该值)可以从选项名称中以 ***空格*** 或 ***=*** 字符给分离出来。`cat` 选项(连同其 `c` 快捷方式)的表现是类似的,但它并非必填项因此不需要一个值。看一眼下面的列表,了解传入的选项的可能组合方式:
|Input|foo|bar|cat|
|:----|:---|:---|:---|
|--bar=Hello|false|"Hello"|null|
|--bar Hello|false|"Hello"|null|
|-b=Hello|false|"=Hello"|null|
|-b Hello|false|"Hello"|null|
|-bHello|false|"Hello"|null|
|-fcWorld -b Hello|true|"Hello"|"World"|
|-cfWorld -b Hello|false|"Hello"|"fWorld"|
|-cbWorld|false|null|"bWorld"|
当命令也接收一个可选参数时,事情变得更加复杂:
```php
// ...
new Definition(array(
// ...
new Argument('arg', Argument::OPTIONAL),
));
```
你可能已经使用了特殊的 -- 分隔符来从参数中分离出选项。看一看下面列表中的第五行,这种用法告诉命令:`World` 是 `arg` 参数的值,而不是可选的 cat 选项的值:
|Input|bar|cat|arg|
|:----|:---|:---|:---|
|--bar Hello|"Hello"|null|null|
|--bar Hello World|"Hello"|null|"World"|
|--bar "Hello World"|"Hello World"|null|null|
|--bar Hello --cat World|"Hello"|"World"|null|
|--bar Hello --cat -- World|"Hello"|null|"World"|
|-b Hello -c World|"Hello"|"World"|null|