mnabialek / laravel-handy-request
允许修改请求数据
Requires
- laravel/framework: 5.*
Requires (Dev)
- fzaninotto/faker: ~1.4
- mockery/mockery: ^0.9.5
- phpunit/phpunit: ^5.4
This package is not auto-updated.
Last update: 2024-09-14 20:15:01 UTC
README
此模块使得在 Laravel 5 应用程序中过滤所有传入的请求变得更容易。例如,假设您想裁剪所有传入的数据,或者可能添加一些不来自外部输入的额外字段,这一切都可以通过几个步骤在整个应用程序中完成。
安装
基本安装
composer require mnabialek/laravel-handy-request
在控制台安装此模块。这就是您需要做的,然而根据您的需求,您可能需要执行一些额外的步骤(见 高级安装)
高级安装
使用此包的默认方式是修改验证前的输入。相同的修改后的输入将在验证后被使用。然而,在某些情况下,您可能根本不想使用验证,或者您想全局修改整个应用程序的输入,并且您仍然想使用默认的 Request iOC 绑定而不是创建自定义的绑定。
如果您想全局应用一些过滤器而不仅仅是针对特定的路由,您需要进行一些额外的修改。假设您将创建自己的 Request 类,在其中您想全局修改您的输入(我们稍后会讨论),并且您可以使用以下命名空间和名称访问此文件 App\Http\Requests\MyRequest
。在这种情况下,要全局使用您的自定义请求,请
- 打开您的
index.php
(默认在public
目录中)并添加
App\Http\Requests\MyRequest::replaceDefaultRequest($app);
just after
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
以确保您的自定义 Request 类将在您的应用程序中使用
- 如果您为您的应用程序使用测试(您绝对应该这样做),您还应进行额外的修改以使测试产生类似的变化。您需要打开
tests/TestCase.php
文件,并在createApplication
方法中添加
\App\Http\Requests\MyRequest::replaceDefaultRequest($app);
just before
$kernel->bootstrap();
执行上述 2 个步骤将允许您在整个应用程序中使用您的自定义 Request 类,并且您可以在应用程序中使用 \Illuminate\Http\Request
依赖注入或 request
容器绑定($app['request'])而不会出现问题。
访问原始和过滤后的输入
包含逻辑的核心文件是 \Mnabialek\LaravelHandyRequest\Traits\HandyRequest
特性。在您的实际应用程序中,您可能想创建自己的特性,该特性扩展了此特性,这将使您更容易在将来进行任何自定义更改。
默认情况下,所有使用 input
的调用都将返回应用了所有您想要应用的所有过滤器的输入。然而,您可以使用 original
方法访问原始输入(不应用过滤器),或者如果您想更明确地访问过滤后的输入,可以使用 filtered
方法。
默认情况下,所有使用 input
、all
、only
、except
等方法的调用都将返回过滤后的输入。然而,如果您想使它们返回原始输入,在扩展原始特性的特性中,您可以像这样覆盖 input
方法
public function input($key = null, $default = null) { return $this->original($key, $default); }
关于过滤的一般信息
为了过滤输入,您需要在要使用过滤输入的请求类中应用前面提到的特性(原始或您自己的自定义特性),如下所示。
use \Mnabialek\LaravelHandyRequest\Traits\HandyRequest;
并定义您想要使用的过滤器。
如果您需要使用全局过滤(在 高级安装 中提到),还有一个创建的 \Mnabialek\LaravelHandyRequest\HandyRequest
类,您应该只扩展您的自定义全局请求类(并在您的类中定义过滤器)
使用过滤器
定义应用过滤器
为了应用任何过滤器,您应该在您的类中定义 $filters
属性,并在其中定义您想要使用的过滤器。过滤器将按照定义的顺序运行。对于每个过滤器,您只能指定过滤器名称或过滤器名称以及您想要包含或排除的字段。
例如
protected $filters = [ 'trim', 'checkbox' => [ 'only' => ['terms', 'checkbox'], 'value' => false, ], 'nullable' => [ 'except' => ['terms', 'active'] ] ];
将导致
trim
过滤器将被用于整个输入checkbox
过滤器将仅用于terms
和checkbox
字段,并且还向此过滤器传递了带有false
值的value
选项。nullable
过滤器将用于所有字段,除了terms
和active
字段
为了指定字段名称,您可以使用显式字段名称,或者您可以使用字段约束(有关详细信息,请参阅 字段约束)。
修改整个输入
有时出于各种原因,您可能需要修改整个输入。例如,您可能想要从输入中删除某些字段或添加另一个字段。您可以使用自定义过滤器或字段方法来实现,但有时没有对整个输入的访问将无法实现。在这种情况下,您可以定义 modifyInput
方法,这将允许您进行此类更改。
例如
protected function modifyInput(array $input) { $input['test'] = ' abc'; unset($input['terms']); return $input; }
将导致您添加新的字段 test
,其值为 abc
,并从输入中完全删除 terms
字段。
请注意,这些修改后的输入将受定义的任何过滤器的影响。因此,在上面的例子中,如果您已定义了 trim
过滤器,则最终您将获得 abc
的值作为 test
字段的值,而不是在 abc
前面带有空格的值。如果您想排除此类字段应用过滤器,您需要为具有此类字段/的所选过滤器使用 except
选项
自定义字段过滤器
在某些情况下,您可能想要为所选字段添加自己的逻辑。为此,您需要创建一个名为 applySampleFieldFilter
的函数,其中 Sample
在此处对应于输入中的 sample
字段。请注意,它不适用于更复杂的字段(例如嵌套数组)。在这种情况下,如果您想为所选字段定义自定义过滤器方法,您需要为每个字段添加 fieldFiltersMethods
属性,其中包含您的自定义方法。例如,它可以看起来像这样
protected $fieldFiltersMethods = [ 'name' => 'filterName', 'address.*' => 'filterAllAddressFields', ];
如您所见,我们为 name
字段和 address.*
字段定义了自定义方法(有关详细信息,请参阅 字段约束)。
无论您是使用默认字段过滤器函数名称还是想定义自定义的,您都需要像这样定义它
protected function filterName($value, $fullKey) { return 'modified '.$value; }
对于此函数,您将获得字段的值以及字段的全键(点表示法)。您当然可以使用 $fullKey
添加任何逻辑,例如,如果您想对除 street
之外的所有 address
字段进行更改,您可以定义 filterAllAddressFields
如下所示
protected function filterAllAddressFields($value, $fullKey) { if ($fullKey == 'address.street') { return $value; } return 'modified '.$value; }
请注意,在定义自定义过滤器方法时,不会应用任何此字段的过滤器。如果您想在您的自定义方法中应用此字段的过滤器,您需要运行
$value = $this->applyFilters($value, $fullKey, $this->normalizedFilters());
以获取由其他过滤器过滤的值,现在您可以为此值添加任何自定义转换。
字段约束
对于 filters
和 fieldFilterMethods
,您都可以使用字段约束。这意味着您不仅可以使用显式字段名称,还可以定义嵌套字段(使用点表示法),或给定字段的所有子字段。例如
name
- 将匹配name
字段。但是,如果您还有name
字段用于address
(因此它是name.address
),则不会匹配address.name
- 将匹配address
中的name
字段people.0.name
- 将匹配第 1 个人的name
字段address.*
- 将匹配address
字段的全部子字段。然而,它不会匹配任何更深层的子字段。例如,它将匹配address.name
字段,但不会匹配address.description.excerpt
字段。address.**
- 将匹配address
字段的全部子字段。例如,它将匹配address.name
字段,也将匹配address.description.excerpt
字段。您应仅在字段约束的末尾使用**
。
过滤器
过滤器类型
一般来说,有两种类型的过滤器
字段过滤器
- 它们作用于单个字段的值全局过滤器
- 它们作用于整个输入。如果您需要基于其他字段进行某些操作或在输入中条件性地添加某些内容(或修改输入),则它们可能很有用。
可用的过滤器
目前有以下过滤器可用。如果您创建任何过滤器并且认为它对其他人也有用,请创建一个带有此(理想情况下包含此过滤器的单元测试)的 Pull request。
trim
它将删除字符串字段的空格
nullable
它将任何空值转换为 null
。请注意,此过滤器不会删除输入,因此如果您发送空格作为值且未使用 trim 过滤器,则它不会被转换为 null
值。
website
如果 URL 字段不为空且不以 http://
或 https://
开头,则它会自动添加 http://
。它不会删除值,因此您可能还需要使用 trim
过滤器。
可用的选项
secure
- 默认设置为false
。如果将其设置为转换为true
的值,则会在需要时添加https://
而不是http://
。
secure_website
与 website
过滤器相同,但默认将 secure
设置为 true
。
checkbox
这是一个全局过滤器。如果字段在输入中不存在,它将自动将值设置为 0
。请注意,它不会对复杂的字段约束(使用 *
或 **
)起作用 - 但它将适用于点表示法中的字段。此过滤器还需要在 only
选项中指定字段(它对 except
选项不起作用)。
可用的选项
value
- 如果您设置任何值,则此值将自动设置到添加的键。默认设置为0
。
定义自定义过滤器
有时内置过滤器不足以满足您的需求,或者您想用您自己的自定义过滤器覆盖内置过滤器以更好地满足您的需求。在这种情况下,您可以创建自己的过滤器类并注册它。您需要在您正在使用的请求类中定义 registerFilters
方法,并在其中调用 registerFilter
方法以注册任何自定义过滤器。例如:
protected function registerFilters() { static::registerFilter('trim', \App\RequestFilters\MyCustomTrimFilter::class); static::registerFilter('new_filter', \App\RequestFilters\BrandNewFilter::class); }
显然,根据您的设置和选择,您也可以在 AppServiceProvider
中定义此类过滤器或扩展基类中的某些请求类,为所有其他请求类定义常用过滤器。
贡献
所有贡献都受到欢迎。特别是如果您想添加一个您认为对许多开发者都有用的新过滤器,您可以创建一个新的 Pull request 来提出此过滤器。
许可
此软件包受 MIT 许可 许可。