thettler/laravel-command-attribute-syntax

该软件包已被废弃,不再维护。未建议替代软件包。

此软件包允许使用PHP属性来指定命令签名

2.0.0 2022-02-09 23:20 UTC

This package is auto-updated.

Last update: 2022-11-10 04:30:42 UTC


README

❌❌此仓库不再支持,请使用 https://github.com/thettler/laravel-console-toolkit ❌❌

Laravel Command Attribute Syntax

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Header Image

此软件包允许您使用PHP属性在Artisan命令上定义参数和选项。您无需触摸现有命令中的 handle() 方法即可使用此软件包。支持所有Laravel功能及更多。

  • 可取消选项
  • 必需值选项
  • 枚举类型
  • 类型转换

💜 支持我

访问我的博客 https://bitbench.dev 或关注我的社交媒体 Twitter @bitbench Instagram @bitbench.dev

📦 安装

您可以通过composer安装此软件包

composer require thettler/laravel-command-attribute-syntax

🔧 使用方法

🗯️ 在您使用此软件包之前,您应该已经了解Artisan命令。您可以在这里了解它们。

基本命令

要使用命令中的属性,您首先需要将默认的 \Illuminate\Console\Command 类替换为 Thettler\LaravelCommandAttributeSyntax\Command。然后,将 Thettler\LaravelCommandAttributeSyntax\Attributes\CommandAttribute 添加到类中。

CommandAttribute 需要设置 name 参数。这将作为命令名称,您可以从命令行调用它。

<?php
namespace App\Console\Commands;

use Thettler\LaravelCommandAttributeSyntax\Attributes\ArtisanCommand;
use Thettler\LaravelCommandAttributeSyntax\Command;

#[ArtisanCommand(
    name: 'basic',
)]
class BasicCommand extends Command
{
    public function handle()
    {
        return 1;
    }
}

然后像这样调用它

php artisan basic
传统语法

    
<?php
namespace App\Console\Commands;

use Illuminate\Console\Command;

class BasicCommand extends Command
{
    protected $signature = 'basic';

    public function handle()
    {
        return 1;
    }
}

描述、帮助和隐藏命令

如果您想添加描述、帮助注释或标记命令为隐藏,您可以在 CommandAttribute 中指定这些内容

#[CommandAttribute(
    name: 'basic',
    description: 'Some useful description.',
    help: 'Some helpful text.',
    hidden: true
)]
class BasicCommand extends Command
{
    ...
}

我喜欢使用命名参数以获得更易读的样式。

传统语法

...
class BasicCommand extends Command
{
    protected $signature = 'basic';

    protected $description = 'Some usefull description.';

    protected $help = 'Some helpfull text.';
    
    protected $hidden = true;
    ...
}

定义输入期望

添加参数或选项的基本工作流程始终是添加一个属性并用属性装饰它。如果您想创建一个选项,请使用 #[Option];如果您想创建一个参数,请使用 #[Argument]。属性将使用来自命令行的值进行填充,因此您可以在 handle() 方法内部像使用任何普通属性一样使用它。您也可以通过常规Laravel方法访问参数和选项,例如 $this->argument('propertyName')$this->option('propertyName')

有关更多信息,请参阅以下部分。⬇️

❗ 属性只能在 handle() 方法内部进行初始化。请记住这一点。

参数

要定义参数,您需要创建一个属性并将其添加到 Argument 属性中。该属性将使用命令行中的值进行初始化,因此您可以在 handle() 方法内部像使用任何普通属性一样使用它。

use \Thettler\LaravelCommandAttributeSyntax\Attributes\Argument;

#[CommandAttribute(
    name: 'basic',
)]
class BasicCommand extends Command
{
    #[Argument]
    protected string $myArgument;
    
    public function handle() {
        $this->line($this->myArgument);
        $this->line($this->argument('myArgument'));
    }
}

调用方式

php artisan basic myValue
# Output:
# myValue
# myValue
传统语法

class BasicCommand extends Command
{
    protected $signature = 'basic {myArgument}';
    
    public function handle() {
        $this->line($this->argument('myArgument'));
    }
}

数组参数

您还可以在参数中使用数组,只需将属性类型提示为 array

#[CommandAttribute(
    name: 'basic',
)]
class BasicCommand extends Command
{
    #[Argument]
    protected array $myArray;
    
    public function handle() {
        $this->line(implode(', ', $this->myArray));
    }
}

调用方式

php artisan basic Item1 Item2 Item3 
# Output
# Item1, Item2, Item3 
传统语法

class BasicCommand extends Command
{
    protected $signature = 'basic {myArgument*}';
    
    public function handle() {
        $this->line($this->argument('myArgument'));
    }
}

可选参数

当然,您也可以使用可选参数。要实现这一点,只需将属性设置为可空即可。

ℹ️ 这也适用于 array,但属性将不会为空,而是为一个空数组

#[CommandAttribute(
    name: 'basic',
)]
class BasicCommand extends Command
{
    #[Argument]
    protected ?string $myArgument;
    
    ...
}
传统语法

class BasicCommand extends Command
{
    protected $signature = 'basic {myArgument?}';
    
    ...
}

如果您的参数应该有一个默认值,您可以将一个值分配给属性,该值将用作默认值。

#[CommandAttribute(
    name: 'basic',
)]
class BasicCommand extends Command
{
    #[Argument]
    protected string $myArgument = 'default';
    
    ...
}
传统语法

class BasicCommand extends Command
{
    protected $signature = 'basic {myArgument=default}';
    
    ...
}

参数描述

您可以在 Argument 属性上设置参数的描述。

#[CommandAttribute(
    name: 'basic',
)]
class BasicCommand extends Command
{
    #[Argument(
        description: 'Argument Description'
    )]
    protected string $myArgument;
    
    ...
}
传统语法

...
class BasicCommand extends Command
{
    protected $signature = 'basic {myArgument: Argument Description}';
    
    ...
}

❗ ❗ 如果您有多个参数,类内部的顺序也将是命令行上的顺序

选项

要使用命令中的选项,您使用 Options 属性。如果已设置 boolean 类型提示,则未设置选项时为 false,设置选项时为 true。

use \Thettler\LaravelCommandAttributeSyntax\Attributes\Option;

#[CommandAttribute(
    name: 'basic',
)]
class BasicCommand extends Command
{
    #[Option]
    protected bool $myOption;
    
    public function handle() {
        dump($this->myOption);
        dump($this->option('myOption'));
    }
}

调用方式

php artisan basic --myOption
# Output
# true
# true
php artisan basic
# Output
# false
# false
传统语法

class BasicCommand extends Command
{
    protected $signature = 'basic {--myOption}';
    
    public function handle() {
        dump($this->option('myOption'));
    }
}

值选项

如果您想向选项添加一个值,只需使用与 bool 不同的类型提示属性。这将自动将其设置为具有值的选项。如果您的类型提示不可为空,则选项将具有必需的值。这意味着选项只能与值一起使用。

❌ 不适用 --myoption ✅ 适用 --myoption=myvalue

如果您想使值可选,只需将类型设置为可空或将值分配给属性

#[CommandAttribute(
    name: 'basic',
)]
class BasicCommand extends Command
{
    #[Option]
    protected string $requiredValue; // if the option is used the User must specify a value  
    
    #[Option]
    protected ?string $optionalValue; // The value is optional

    #[Option]
    protected string $defaultValue = 'default'; // The option has a default value

    #[Option]
    protected array $array; // an Array Option 

    #[Option]
    protected array $defaultArray = ['default1', 'default2']; // an Array Option with default
    ...
}

调用方式

php artisan basic --requiredValue=someValue --optionalValue --array=Item1 --array=Item2
传统语法

class BasicCommand extends Command
{
    // requiredValue is not possible
    // defaultArray is not possible
    protected $signature = 'basic {--optionalValue=} {--defaultValue=default} {--array=*}';
   
   ...
}

选项描述

您可以在 Option 属性上设置选项的描述。

#[CommandAttribute(
    name: 'basic',
)]
class BasicCommand extends Command
{
    #[Option(
        description: 'Option Description'
    )]
    protected bool $option;
    ...
}
传统语法

class BasicCommand extends Command
{
    protected $signature = 'basic {--option: Option Description}';
}

选项快捷方式

您可以在 Option 属性上设置选项的快捷方式。

⚠️ 注意,快捷方式只能有一个字符长

#[CommandAttribute(
    name: 'basic',
)]
class BasicCommand extends Command
{
    #[Option(
        shortcut: 'Q'
    )]
    protected bool $option;
    ...
}

调用方式

php artisan basic -Q
传统语法

class BasicCommand extends Command
{
    protected $signature = 'basic {--Q|option}';
}

选项别名

默认情况下,命令行上使用的选项名称将与属性名称相同。您可以通过 Option 属性上的 name 参数来更改此设置。这如果您有冲突的属性名称或希望为您的命令提供更易表达的 API,将很有用。

⚠️ 如果您使用 ->option() 语法,则需要指定别名名称以获取选项。

#[CommandAttribute(
    name: 'basic',
)]
class BasicCommand extends Command
{
    #[Option(
        name: 'alternativeName'
    )]
    protected bool $myOption;
    
    public function handle(){
       dump($this->myOption);
       dump($this->option('alternativeName'))
    }
}

调用方式

php artisan basic --alternativeName

可否定选项

您可以通过向 Option 属性添加可否定参数来使选项可否定。现在,选项接受标志(例如,--yell)或其否定(例如,--no-yell)。

#[CommandAttribute(
    name: 'basic',
)]
class BasicCommand extends Command
{
    #[Option(
        negatable: true
    )]
    protected bool $yell;
    
    public function handle(){
       dump($this->yell); // true if called with --yell
       dump($this->yell); // false if called with --no-yell
    }
}

调用方式

php artisan basic --yell
php artisan basic --no-yell

枚举类型

还可以将 ArgumentsOptions 作为枚举类型输入。包将自动将命令行输入转换为枚举类型。如果使用 BackedEnums,则使用 case 的值;如果使用非 backed 枚举,则使用 Case 的名称。

enum Enum
{
    case A;
    case B;
    case C;
}

enum IntEnum: int
{
    case A = 1;
    case B = 2;
    case C = 3;
}

enum StringEnum: string
{
    case A = 'String A';
    case B = 'String B';
    case C = 'String C';
}
    #[Argument]
    protected Enum $argEnum;

    #[Argument]
    protected StringEnum $argStringEnum;

    #[Argument]
    protected IntEnum $argIntEnum;

    #[Option]
    protected Enum $enum;

    #[Option]
    protected StringEnum $stringEnum;

    #[Option]
    protected IntEnum $intEnum;
php artisan enum B "String B" 2 --enum=B --stringEnum="String B" --intEnum=2

转换

还可以定义自己的转换。为此,您需要创建一个实现 CastInterface 的类。match() 方法检查类型是否可以通过此转换类进行转换,如果可以则返回 true,否则返回 false

让我们看看一个小型的 UserCast,它允许在命令行上简单地使用用户模型的 id,并自动从数据库中获取正确的用户。

<?php

namespace Thettler\LaravelCommandAttributeSyntax\Casts;

use Thettler\LaravelCommandAttributeSyntax\Contracts\CastInterface;

class UserCast implements CastInterface
{
     public static function match(string $typeName, mixed $value): bool
    {
        return $typeName === User::class;
    }

    public function cast(mixed $value, string $typeName): User
    {
        return User::find($value);
    }
}

要注册您的转换,首先需要发布配置文件。

php artisan vendor:publish --tag="command-attribute-syntax-config"

然后将您的转换添加到转换数组中。

return [
    'casts' => [
            \Thettler\LaravelCommandAttributeSyntax\Casts\UserCast::class
    ]
];

包从数组顶部到底部进行遍历,并使用第一个从 match() 方法返回 true 的转换。

现在,最后给我们的 Argument(或 Option)添加类型提示。

#[CommandAttribute(name: 'userName')]
class UserNameCommand extends \Thettler\LaravelCommandAttributeSyntax\Command
{
    #[Argument]
    protected User $user;

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $this->line($this->user->name);
    }
}
php artisan userName 2
 // Some Name

🤖 测试

composer test

📖 更新日志

有关最近更改的更多信息,请参阅 更新日志

👼 贡献

有关详细信息,请参阅 贡献指南

🔒 安全漏洞

有关如何报告安全漏洞的详细信息,请参阅 我们的安全策略

©️ 致谢

📚 许可证

MIT 许可证(MIT)。有关更多信息,请参阅 许可证文件