zachflower/eloquent-interactions

Laravel 的交互模式实现。

v1.0.0 2024-02-18 00:30 UTC

This package is auto-updated.

Last update: 2024-09-18 02:06:23 UTC


README

Eloquent Interactions 管理应用特定的业务逻辑。它是在 PHP for Laravel 中的命令模式实现,灵感来源于 Ruby 中的 ActiveInteraction 库。

Latest Stable Version CI

Eloquent Interactions 为您提供了一个放置业务逻辑的地方。它还通过验证您的输入是否符合预期来帮助您编写更安全的代码,并提供了创建离散、易于测试的代码的平台。

安装

要安装 Eloquent Interactions,请通过 Composer 需求库。

composer require zachflower/eloquent-interactions

Eloquent Interactions 考虑到 Laravel 7.0+ 进行构建,目前测试正在验证与 Laravel 7、8、9 和 10 的兼容性,PHP 版本从 7.2.5 到 8.3。如果您发现与您特定的 Laravel 或 PHP 版本有任何问题,请 创建问题,我会尽力解决。

基本使用

要开始使用 Eloquent Interactions,首先创建一个新的交互。交互通常位于 app/Interactions 目录中,但您可以根据您的 composer.json 文件将其放置在可以自动加载的任何位置。所有 Eloquent Interactions 都扩展了 \ZachFlower\EloquentInteractions\Interaction 抽象类。

创建交互的最简单方法是使用 make:interaction Artisan 命令

php artisan make:interaction ConvertMetersToMiles

现在,让我们看一下上面 make:interaction 命令创建的基交互

<?php

namespace App\Interactions;

use ZachFlower\EloquentInteractions\Interaction;

class ConvertMetersToMiles extends Interaction
{
    /**
     * Parameter validations
     *
     * @var array
     */
    public $validations = [
        //
    ];

    /**
     * Execute the interaction
     *
     * @return void
     */
    public function execute() {
        //
    }
}

一旦生成,每个交互都需要以下两个组件

  1. 输入验证。类 $validations 属性使用内置的 Laravel 验证器 定义和验证给定交互的预期输入。或者,可以用 validations() 方法替换 $validations 属性。
  2. 业务逻辑execute() 方法接收提供输入(当然是在通过验证之后)并在其上执行必要的业务逻辑。您定义的每个输入都将可用。如果有任何输入无效,则不会运行 execute()

有了这些信息,让我们更新生成的交互以使其可用

<?php

namespace App\Interactions;

use ZachFlower\EloquentInteractions\Interaction;

class ConvertMetersToMiles extends Interaction
{
    /**
     * Parameter validations
     *
     * @var array
     */
    public $validations = [
        'meters' => 'required|numeric|min:0',
    ];

    /**
     * Execute the interaction
     *
     * @return void
     */
    public function execute() {
        return $this->meters * 0.000621371;
    }
}

要执行交互,您可以在类上调用静态 run() 方法。由于交互的 $validations 属性定义了预期的输入,应将简单的键值数组传递给 run(),其中包含预期的输入。此方法将返回一个 \ZachFlower\EloquentInteractions\Outcome 类的新实例。要检查结果的成功,Outcome 对象上的 $valid 属性将被设置为布尔值,其中 TRUE 表示输入验证通过,而 FALSE 表示失败。如果验证失败,所有验证错误都将存储在 Outcome 对象上的 $errors 属性中。如果验证通过,则 execute() 方法返回的值将存储在 Outcome 对象上的 $result 属性中。

>>> $outcome = ConvertMetersToMiles::run(['meters' => 100]);
>>> $outcome->valid;
=> true
>>> $outcome->result;
=> 0.0621371

>>> $outcome = ConvertMetersToMiles::run(['meters' => 'one hundred']);
>>> $outcome->valid;
=> false
>>> $outcome->errors->toArray()
=> [
     "meters" => [
       "The meters field must be a number.",
     ],
   ]

如果您希望自行处理错误处理,可以在run()方法的第二个参数中传递TRUE。这,姑且这么说,将以“危险”的方式执行交互,意味着任何定义的错误都将被抛出为类型为\ZachFlower\EloquentInteractions\Exceptions\ValidationException的异常。

>>> $outcome = App\Interactions\Utility\ConvertMetersToMiles::run(['meters' => 'one hundred'], TRUE);
Illuminate\Validation\ValidationException with message 'The given data failed to pass validation.'
>>> $outcome->errors->toArray();
=> [
     "meters" => [
       "The meters field must be a number.",
     ],
   ]

验证

Eloquent Interactions高度依赖于内置的Laravel验证器。这意味着在Laravel应用程序中可用的任何验证方法也将可用于Eloquent Interactions验证器。话虽如此,目前有一个自定义验证器(更多即将推出),以更好地支持Eloquent Interactions的后端特性。

高级验证器

如果内置的验证器无法满足您的需求,您可以使用validations()方法代替$validations属性。例如,假设我们想在上面的示例中使用一个类来验证meters参数。我们的交互将更改为如下所示

<?php

namespace App\Interactions;

use ZachFlower\EloquentInteractions\Interaction;

class ConvertMetersToMiles extends Interaction
{
    /**
     * Execute the interaction
     *
     * @return void
     */
    public function execute() {
        return $this->meters * 0.000621371;
    }

    /**
     * Parameter validations
     *
     * @var array
     */
    public function validations()
    {
        return [
            'meters' => ['required', new MyMetersRule()],
        ];
    }
}

对象

在某些情况下,可能需要验证对象的类型。例如,如果我们想验证输入参数是User模型,可以使用以下验证规则

public $validations = [
    'user' => 'required|object:App\Models\User'
];

总的来说,这个验证器检查输入参数的instanceof与定义的验证是否匹配。这在验证提供的对象是否是定义的验证对象子类时特别有用。

错误

除了内置的验证错误之外,Eloquent Interactions还在execute()方法中支持自定义验证错误。这可以通过直接在Laravel验证器的errors()方法上使用其自己的add()方法来实现

public function execute() {
    $this->validator->errors()->add('entity', 'The entity object type is invalid.');
}

请注意,虽然在execute()方法中添加自定义验证错误确实会将Outcome标记为无效并返回预期的错误消息,但它不会停止交互执行,所以除非采取特殊步骤,否则execute()方法中的任何业务逻辑都会按正常方式执行。

贡献

请阅读贡献指南。其中包含打开问题、编码标准和开发说明。

对于个人支持请求,请使用Gitter获取帮助。

版本控制

为了提高发布周期的透明度并努力保持向后兼容性,Eloquent Interactions遵循语义版本控制指南。有时我会犯错误,但我会尽可能遵守这些规则。

请参阅GitHub项目中的发布部分,以获取Eloquent Interactions每个发布版本的变更日志。

支持

问题跟踪器是报告错误、提出功能请求和提交拉取请求的首选渠道。

版权和许可

代码和文档版权所有2024年Zachary Flower。代码在MIT许可下发布。