Laravel 5.2 - 扩展Validator类

时间:2016-04-03 17:17:17

标签: php laravel-5 laravel-5.2 laravel-validation laravel-request

我正在尝试覆盖doReplacements中的Illuminate\Validation\Validator方法。当我扩展本机ValidatorRequest类时,我收到此错误:

  

Route.php第270行中的ReflectionException:

     

Class App \ Http \ Requests \ FooRequest不存在

这就是我所做的:

  1. 扩展原生Illuminate\Validation\Validator

    class MyCustomValidator extends Validator {
    
        protected function doReplacements($message, $attribute, $rule, $parameters) {
            //override this method
        }
    
    }
    
  2. 在原生MyCustomValidator的抽象扩展名中使用App\Http\Requests\Request

    abstract class MyCustomRequest extends Request {
    
        //Override native method by injecting the extending validator
        protected function formatErrors( MyCustomValidator $validator )
        {
            return $validator->getMessageBag()->toArray();
        }
    }
    
  3. 使用具体类扩展MyCustomRequest

    class FooRequest extends MyCustomRequest
    {
    
        public function authorize()
        {
            return true;
        }
    
    
        public function rules()
        {
            return [
                // rules go here
            ];
        }
    }
    
  4. 在控制器方法中使用FooRequest

    public function store(FooRequest $request) {
        //use the request and persist
    }
    
  5. <小时/> 我猜我缺少必需的外观,提供者或容器绑定。我仍然在学习这些主题,并且不能很好地理解这些主题,以便了解下一步。

    参考文献:

    • Custom validator in Laravel 5 - 我按照答案,但仍然有同样的错误。我想知道在解决我在这里尝试的问题之前,这是否与我的问题有很大关系。

    • Extending Custom Validation-Class - 问题看起来很相似,回答建议使用Validator::extend,我知道可以在AppServiceProvider中完成,但理想情况下我的代码应该在自己的供应商包中。再次,不确定是否相关。

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,这就是我所做的。

首先,创建一个类并将其命名为 CustomValidatorServiceProvider 或任何您想要的名称。在 CustomValidatorServiceProvider 内添加以下行。

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Event;
use Illuminate\Validation\ValidationServiceProvider as ServiceProvider;
use App\Services\Validator\Factory;

class CustomValidatorServiceProvider extends ServiceProvider
{

    /**
     * Register the validation factory.
     *
     * @return void
     */
    protected function registerValidationFactory()
    {
        $this->app->singleton('validator', function ($app) {
            $validator = new Factory($app['translator'], $app);

            // The validation presence verifier is responsible for determining the existence
            // of values in a given data collection, typically a relational database or
            // other persistent data stores. And it is used to check for uniqueness.
            if (isset($app['db']) && isset($app['validation.presence'])) {
                $validator->setPresenceVerifier($app['validation.presence']);
            }

            return $validator;
        });
    }

}

如果您发现我添加了自己的 Validator \ Factory 并导入了它。  在 Validator \ Factory 内部,我有以下代码。

<?php

namespace App\Services\Validator;

use Illuminate\Validation\Factory as ParentFactory;

class Factory extends ParentFactory
{

    /**
     * Resolve a new Validator instance.
     *
     * @param  array  $data
     * @param  array  $rules
     * @param  array  $messages
     * @param  array  $customAttributes
     * @return \Illuminate\Validation\Validator
     */
    protected function resolve(array $data, array $rules, array $messages, array $customAttributes)
    {
        if (is_null($this->resolver)) {
            return new Validator($this->translator, $data, $rules, $messages, $customAttributes);
        }

        return call_user_func($this->resolver, $this->translator, $data, $rules, $messages, $customAttributes);
    }
}

Validator \ Factory 所在的同一目录中,我还添加了自定义验证程序类,它将扩展验证程序类框架。它包含以下代码。

<?php

namespace App\Services\Validator;

use Illuminate\Validation\Validator as ParentValidator;
use Illuminate\Support\Str;

class Validator extends ParentValidator
{

    /**
     * Replace all place-holders for the greater_than_equal rule.
     *
     * @param  string  $message
     * @param  string  $attribute
     * @param  string  $rule
     * @param  array   $parameters
     * @return string
     */
    protected function replaceGreaterThanEqual($message, $attribute, $rule, $parameters)
    {
        $replacers[0] = str_replace('_', ' ', Str::snake($parameters[0]));
        $replacers[1] = $attribute;
        return str_replace([':other', ':attribute'], $replacers, $message);
    }

    /**
     * Replace all place-holders for the after_or_equal rule.
     *
     * @param  string  $message
     * @param  string  $attribute
     * @param  string  $rule
     * @param  array   $parameters
     * @return string
     */
    protected function replaceAfterOrEqual($message, $attribute, $rule, $parameters)
    {
        return $this->replaceGreaterThanEqual($message, $attribute, $rule, $parameters);
    }
}

最后,我们应该在提供商数组下添加我们在 config / app.php 中创建的服务提供商

App\Providers\CustomValidatorServiceProvider::class,

您已经可以删除或注释掉 ValidationServiceProvider

Illuminate\Validation\ValidationServiceProvider::class,

答案 1 :(得分:-1)

您可以做的是将validator规则添加到Request课程中,例如:

public function validator(\Illuminate\Contracts\Validation\Factory $factory)
{
    $this->addExtraRules($factory);

    return $factory->make(
        $this->all(), $this->container->call([$this, 'rules']),
        $this->messages(), $this->attributes()
    );
}

现在您需要实现addExtraRules方法,例如:

protected function addExtraRules(\Illuminate\Contracts\Validation\Factory $validator)
{
    $validator->extendImplicit('equals_2',
        function ($attribute, $value, $parameters, $validator) {
           return $value == 2;
        });
}

关于这个错误:App\Http\Requests\FooRequest,请确保以这种方式在FooRequest类文件中定义了命名空间:

namespace App\Http\Requests;