新金沙3777

还有就是通过Facades的方式创建验证器对象,Laravel 5.5 将提供一个全新的自定义验证规则的对象

三月 11th, 2020  |  未分类

可以看出,最终创建验证器是通过实现IlluminateContractsValidationFactory接口的IlluminateValidationFactory类创建的。再来看看,这个工厂类怎么创建实际的验证器的。

4、契约列表

下面是Laravel契约列表,以及其对应的“门面”:

Contract
References Facade

IlluminateContractsAuthFactory
Auth

IlluminateContractsAuthPasswordBroker
Password

IlluminateContractsBusDispatcher
Bus

IlluminateContractsBroadcastingBroadcaster

IlluminateContractsCacheRepository
Cache

IlluminateContractsCacheFactory
Cache::driver()

IlluminateContractsConfigRepository
Config

IlluminateContractsContainerContainer
App

IlluminateContractsCookieFactory
Cookie

IlluminateContractsCookieQueueingFactory
Cookie::queue()

IlluminateContractsEncryptionEncrypter
Crypt

IlluminateContractsEventsDispatcher
Event

IlluminateContractsFilesystemCloud

IlluminateContractsFilesystemFactory
File

IlluminateContractsFilesystemFilesystem
File

IlluminateContractsFoundationApplication
App

IlluminateContractsHashingHasher
Hash

IlluminateContractsLoggingLog
Log

IlluminateContractsMailMailQueue
Mail::queue()

IlluminateContractsMailMailer
Mail

IlluminateContractsQueueFactory
Queue::driver()

IlluminateContractsQueueQueue
Queue

IlluminateContractsRedisDatabase
Redis

IlluminateContractsRoutingRegistrar
Route

IlluminateContractsRoutingResponseFactory
Response

IlluminateContractsRoutingUrlGenerator
URL

IlluminateContractsSupportArrayable

IlluminateContractsSupportJsonable

IlluminateContractsSupportRenderable

IlluminateContractsValidationFactory
Validator::make()

IlluminateContractsValidationValidator

IlluminateContractsViewFactory
View::make()

IlluminateContractsViewView

Laravel 5.5 将提供一个全新的自定义验证规则的对象,以作为原来的
Validator::extend
方法的替代。。很多时候我们会直接用正则表达式来处理这种特殊的验证,也有时候我们会选择用
Validator::extend 来扩展一个自定义的规则。但在 Laravel 5.5
版本中,我们有了新的手段,只要定义一个实现
IlluminateContractsValidationRule
接口的类即可实现自定义的验证规则,并可以直接使用。

2 通过自定义规则类扩展

2、何时使用契约

正如上面所讨论的,大多数情况下使用契约还是门面取决于个人或团队的喜好,契约和门面都可以用于创建强大的、测试友好的Laravel应用。只要你保持类的职责单一,你会发现使用契约和门面并没有什么实质性的差别。

但是,对契约你可能还是有些疑问。例如,为什么要全部使用接口?使用接口是不是更复杂?下面让我们从两个方面来扒一扒为什么使用接口:松耦合和简单。

同样的效果,也可以通过匿名函数来实现:

Laravel本身提供了很多通用的参数验证规则,但是对于一些特定的场景,还是需要提供验证规则的扩展。

松耦合

首先,让我们看看一些缓存实现的紧耦合代码:

<?php

namespace AppOrders;

class Repository{
    /**
     * 缓存
     */
    protected $cache;

    /**
     * 创建一个新的Repository实例
     *
     * @param  SomePackageCacheMemcached  $cache
     * @return void
     */
    public function __construct(SomePackageCacheMemcached $cache)
    {
        $this->cache = $cache;
    }

    /**
     * 通过ID获取订单
     *
     * @param  int  $id
     * @return Order
     */
    public function find($id)
    {
        if ($this->cache->has($id))    {
            //
        }
    }
}

在这个类中,代码和给定缓存实现紧密耦合,由于我们基于一个来自包的具体的缓存类,如果包的API变了,那么相应的,我们的代码必须做修改。

类似的,如果我们想要替换底层的缓存技术(Memcached)为别的技术实现(Redis),我们将再一次不得不修改我们的代码库。我们的代码库应该并不知道谁提供的数据或者数据是怎么提供的。

我们可以基于一种简单的、与提供者无关的接口来优化我们的代码,从而替代上述那种实现:

<?php

namespace AppOrders;

use IlluminateContractsCacheRepository as Cache;

class Repository{
    /**
     * 创建一个新的Repository实例
     *
     * @param  Cache  $cache
     * @return void
     */
    public function __construct(Cache $cache)
    {
        $this->cache = $cache;
    }
}

现在代码就不与任何特定提供者耦合,甚至与Laravel都是无关的。由于契约包不包含任何实现和依赖,你可以轻松的为给定契约编写可选实现代码,你可以随意替换缓存实现而不用去修改任何缓存消费代码。

config/app.php 中注册了’Validator’ =>
IlluminateSupportFacadesValidator::class。

1、简介

Laravel中的契约是指框架提供的一系列定义核心服务的接口。
例如
IlluminateContractsQueueQueue契约定义了队列任务需要实现的方法,IlluminateContractsMailMailer契约定义了发送邮件所需要实现的方法。

每一个契约都有框架提供的相应实现。例如,Laravel为队列提供了多个驱动的实现,邮件则由
SwiftMailer驱动 实现 。

所有Laravel契约都有其对应的GitHub库,这为所有有效的契约提供了快速入门指南,同时也可以作为独立、解耦的包被包开发者使用。

匿名函数的自定义验证规则在一次性的简单验证逻辑中用起来确实会很方便,或者是在编码过程中快速测试验证逻辑也很实用。但是总的来说,还是建议采用更具组织性和可读性的自定义验证类。最佳方法是在编写
Controller
的过程中用匿名函数快速验证自定义规则,然后再把它移到自定义的验证类对象中。

Laravel验证规则的扩展有两种方式。

简单

当所有Laravel服务都统一在简单接口中定义,很容易判断给定服务提供的功能。契约可以充当框架特性的简明文档。

此外,基于简单接口,代码也更容易理解和维护。在一个庞大而复杂的类中,与其追踪哪些方法是有效的,不如转向简单、干净的接口。

在验证的表单项为空值或者不存在的时候,对应的自定义验证规则不会执行。这个与系统自带的验证规则的逻辑是一致的。如果你希望你的自定义验证规则,即使是在对应的表单项为空值时也被执行的话,那么只要把继承的接口从
rule 改成 ImplicitRule 即可:

一,创建一个自定义的工厂类。然后在AppServiceProvider中重新绑定新的验证器工厂创建类;

契约(Contracts) VS 门面(Facades)

十大正规网赌网址 ,Laravel门面为Laravel服务的使用提供了便捷方式——不再需要从服务容器中类型提示和契约
解析即可直接通过静态门面调用
。有些开发者喜欢这种便捷,不过也有开发者倾向于使用契约,他们喜欢定义明确的依赖。

注:大多数应用中,不管你使用门面还是契约,合适就好。不过,如果你是在构建一个扩展包,那么就应该使用契约,因为这在扩展包中更容易测试。

以上所述是小编给大家介绍的Laravel 5.5
的自定义验证对象/类示例代码详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

例如,一个验证规则如下,表示用当期类的validateMinNum对参数进行验证,那么,这样的一个功能,如何在Laravel中实现呢。

3、如何使用契约

那么,如何实现契约呢?这很简单。

Laravel中很多类都是通过服务容器进行解析,包括控制器,以及监听器、中间件、队列任务,甚至路由闭包。所以,要实现一个契约,需要在解析类的构造函数中类型提示这个契约接口。

例如,看看下面这个事件监听器:

<?php

namespace AppListeners;

use AppUser;
use AppEventsOrderWasPlaced;
use IlluminateContractsRedisDatabase;

class CacheOrderInformation
{
    /**
     * The Redis database implementation.
     */
    protected $redis;

    /**
     * Create a new event handler instance.
     *
     * @param  Database  $redis
     * @return void
     */
    public function __construct(Database $redis)
    {
        $this->redis = $redis;
    }

    /**
     * Handle the event.
     *
     * @param  OrderWasPlaced  $event
     * @return void
     */
    public function handle(OrderWasPlaced $event)
    {
        //
    }
}

事件监听器被解析的时候,服务容器会读取构造函数中的类型提示,并注入适当的值。要学习更多关于服务容器的注册细节,参考其文档。

public function handlForm{ $this->validate($request, [ 'oddField' => [new IsOddValidationRule] ]);}

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。

 

Laravel 5.5 将提供一个全新的自定义验证规则的对象,以作为原来的
Validator::extend 方法的替代。

从上面可以看出,Validator的实际实现类是容器中的validator对象,那这个validator对象是哪个?namespace IlluminateFoundation;...class Application extends Container implements ApplicationContract, HttpKernelInterface{ ... public function registerCoreContainerAliases() { foreach ([ ... 'validator'=> [ IlluminateValidationFactory::class, IlluminateContractsValidationFactory::class ], ]) ... } ...}

下面是一个简单的示例:

到这里,可以看出Laravel的验证器的创建都是通过特定的工厂类创建。

class IsOddValidationRule implements ImplicitRule{ ...}

像Yii2中,因为基本上所有的对象都有验证方法,所以很容易用当期类方法作为验证规则验证函数。

采用 Laravel 5.5
新增的自定义验证类,可以更好地管理大量的自定义验证规则,而且在 PHPStorm
之类的 IDE
中,从验证代码里快速跳转到对应的验证类的代码也会更方便。毕竟采用
Validator::extend
的话,你只能通过搜索对应验证类名称的字符串来找到规则定义的源代码。

如何实现用当期类方法作为验证规则验证函数

你可以查看该功能在 Laravel 框架的 github 上的 Pull Request
,阅读具体的实现代码以及相关的测试代码。

Laravel
文档调用验证器,除了通过控制器,还有就是通过Facades的方式创建验证器对象。Validator::make。

public function handleForm{ $this->validate($request, [ 'oddField' => [function($attributes, $value, $fail) { if  { $fail; } }] ]);}

Laravel本身提供了ClosureValidationRule的验证规则用于处理回调函数验证规则。同时也可以使用extend方式进行回调函数的验证。

参考

1 通过extend方法扩展

use IlluminateContractsValidationRule;class IsOddValidationRule implements Rule{ public function passes { return ; } public function message() { return ':attribute 必须是奇数'; }}

但是这种方式对验证器的影响是全局的。不建议使用。

总结

//这是一个简单的参数比较的验证规则,Laravel5.8中提供,Laravel5.5中未提供//验证规则如下: 'max_num'=>'gte:min',Validator::extend('gte',function($attribute, $value, $parameters, $validator){ if($value>=data_get,$parameters[0])) { return true; } return false;});

//IlluminateContractsValidationFactory 源码public function extend($rule, $extension, $message = null){ $this->extensions[$rule] = $extension; if  { $this->fallbackMessages[Str::snake] = $message; }}

//IlluminateValidationValidator 源码protected function callExtension{ $callback = $this->extensions[$rule]; if (is_callable { return call_user_func_array($callback, $parameters); } elseif  { return $this->callClassBasedExtension($callback, $parameters); }}protected function validateAttribute{ ... $method = "validate{$rule}"; if ($validatable && ! $this->$method($attribute, $value, $parameters, $this)) { $this->addFailure($attribute, $rule, $parameters); }}public function __call{ $rule = Str::snake; if (isset($this->extensions[$rule])) { return $this->callExtension; } throw new BadMethodCallException(sprintf( 'Method %s::%s does not exist.', static::class, $method ));}

以上代码定义了一个 IsOddValidationRule 的自定义验证类,在 Controller
中要使用这个验证类的话,可以这样写:

Validator::resolver(function($translator, $data, $rules, $messages, $customAttributes){ return new ExtendValidator($translator, $data, $rules, $messages, $customAttributes);});

验证规则的扩展有两种方式,一种是通过extend方式实现。extend方式对验证器的影响是全局的,整个运行进程有效。可以获取到验证器本身,因此可以做多个字段关系的验证;另一种是通过自定义规则类实现。自定义规则了只对使用自定义规则类的验证有效。但是自定义规则类本身无法直接获取到验证器本身,不能够做多个字段关系的验证。如果需要实现,则需要使用自定义验证器,将验证器传入到验证规则中去。

方法1 通过自定义类实现
Laravel提供了ClosureValidationRule自定义验证类,用来添加回调函数的验证。

$rule = [ 'min'=>'checkv'];Validator::extend('checkv',[$this,'checkv']);

Laravel
中提供了Illuminate新金沙3777 ,ContractsValidationRule接口,只有实现了这个接口的类都认为是符合的自定义验证规则类。

Factory提供了extend方法用于扩展规则验证方法。所有的扩展规则最终都会被传到验证器中。验证器在验证参数的过程中,如果找到匹配的验证规则,则直接进行验证。否则调用魔术方法__call查找扩展验证函数。扩展函数返回布尔值,返回true则表示验证通过,返回false表示验证失败。

//IlluminateContractsValidationFactory 源码protected function resolve(array $data, array $rules, array $messages, array $customAttributes){ if (is_null { return new Validator( $this->translator, $data, $rules, $messages, $customAttributes ); } return call_user_func( $this->resolver, $this->translator, $data, $rules, $messages, $customAttributes );}

总结

验证器怎么创建的,谁创建的

二,AppServiceProvider中通过resolver方法设置工厂类的resolver属性,接管验证器的实例化,例如:

如果需要自定义验证器类(比如我需要把5.8的一些新功能迁移到5.5的版本上),有两种方式:

['min_num'=>'validateMinNum']
$rule = [ 'min'=>new ClosureValidationRule];$data = ['min'=>10];$v = Validator::make;
自定义规则类需要实现的方法有passes方法,用于验证参数是否合法。message方法,用于提供验证失败的错误提示信息。使用自定义验证类,相对于extend方法扩展有一个很大的bug就是无法在自定义类中获取到当期的验证器对象。从而导致在当前扩展的验证规则中,只能过获取到需要验证的数据,而获取不到其他的字段数据,无法进行联合字段的验证。像上面比较两个字段的大小的验证规则就无法实现。如果想要通过自定义验证规则类实现上面两个字段大小比较的验证规则,则需要自定义验证类,修改validateUsingCustomRule方法,将当期验证器传入到自定义验证规则实例对象中去。protected function validateUsingCustomRule($attribute, $value, $rule){ if(method_exists($rule, 'setValidator')) { $rule->setValidator; } return parent::validateUsingCustomRule($attribute,$value,$rule);}

通过以上源码的学习,可以看出Laravel验证器的创建都是用过验证器工厂类创建的。如果需要自定义验证器,可以通过修改验证器工厂类,或者设置验证器工厂类的resolver属性接管验证器的实例化。

如何自定义验证规则

方法2 通过extend方式实现

相关文章

Your Comments

近期评论

    分类目录

    • 没有分类目录

    功能


    网站地图xml地图