【问题标题】:2 custom validators in Laravel as service providersLaravel 中的 2 个自定义验证器作为服务提供者
【发布时间】:2014-11-09 12:54:18
【问题描述】:

在我的 Laravel 项目中,我使用 unique_with 验证器,基本上我有 textarea 允许我添加批量类别。我需要验证此文本区域的每一行,因为将在数据库中添加多行,所以我还需要使用我的自定义验证器。

在我使用的app/config/app.php 文件中:

'Felixkiss\UniqueWithValidator\UniqueWithValidatorServiceProvider',
'Providers\TextareaNameValidatorServiceProvider',

注册这个验证器和我的自定义验证器。

我用于验证的代码是:

    $data = Input::except('submit');
    $data['parent'] = Input::get('parent') ?: null;


    $names = explode(PHP_EOL, trim($data['name']));

    if (count($names) == 1) {
        $rules['name']
            = '
            required |
            unique_with:categories, parent = par_cat';
    }
    else {
        $rules['name'] = 'textareaname'; // my custom validator
    }


    $validator = Validator::make($data, $rules,
        Lang::get('forms.validation'));


    if ($validator->passes()) {
    // ...

如果我只有一行,它可以正常工作,因为它使用unique_with 验证器。

我的验证器是这样定义的:

服务提供商:

<?php

namespace Providers;

use Illuminate\Support\ServiceProvider;

class TextareaNameValidatorServiceProvider extends ServiceProvider {

    public function register(){}

    public function boot()
    {
        $this->app->validator->resolver(function($translator, $data, $rules, $messages)
        {
            return new \Utils\TextareaNameValidator($translator, $data, $rules, $messages);
        });
    }

}

验证器本身

<?php

namespace Utils;

use Validator;


class TextareaNameValidator extends \Illuminate\Validation\Validator
{
    public function validateTextareaName($attribute, $value, $parameters)
    {
        $array = explode(PHP_EOL, trim($value));

        if (count($array) !== count(array_unique($array))) {
            return false;
        }


        foreach ($array as $item) {
            $data['name'] = $item;



            $rules['name']
                = '
                required |
                unique_with:categories, parent = par_cat ';

            $validator = Validator::make($data, $rules);

            if (!$validator->passes()) {
                return false;
            }
        }

        return true;
    }
}

如果我运行此代码并转到textareaname 验证器,并故意填写unique_with 需要在此验证器中运行的方式,我会得到:

方法 [validateUniqueWith] 不存在。

但是正如我所说,当unique_with 验证器不是从textareaname 验证器运行时,不会发生错误。

如果我将供应商中的订单从以下位置更改:

'Felixkiss\UniqueWithValidator\UniqueWithValidatorServiceProvider',
'Providers\TextareaNameValidatorServiceProvider',

'Providers\TextareaNameValidatorServiceProvider',
'Felixkiss\UniqueWithValidator\UniqueWithValidatorServiceProvider',

我收到以下错误:

方法 [validateTextareaname] 不存在。

因此,使用 2 个自定义验证器似乎存在问题。

问题是 - 如何在 Laravel 中注册 2 个没有此类问题的自定义验证器?或者可能由于某种原因,无法从另一个自定义验证器运行自定义验证器(但是在更改提供程序的顺序时查看错误会导致类似的错误,似乎并非如此)?

编辑

在尝试解决此问题时,我将代码移至不使用服务提供商。所以我在app/config/app.php评论了这一行:

// 'Providers\TextareaNameValidatorServiceProvider',

并在我的app/start/global.php 中添加了:

Validator::extend('TextareaName', function($attribute, $value, $parameters)
{
    $array = explode(PHP_EOL, trim($value));

    if (count($array) !== count(array_unique($array))) {
        return false;
    }


    foreach ($array as $item) {
        $data['name'] = $item;



        $rules['name']
            = '
                required |
                unique_with:categories, parent = par_cat ';

        $validator = Validator::make($data, $rules);

        if (!$validator->passes()) {
            return false;
        }
    }

    return true;
});

验证器中的代码与之前相同。现在它可以正常工作了。所以问题是当我使用服务提供商注册我的验证器时。问题是 - 为什么?

EDIT2

即使我的 2 个自定义验证器使用服务提供者(而不是使用 unique_with),它似乎也会发生。如果我复制我的 TextAreaName(服务提供者和验证者)的代码,正确地重命名它们并将它们都添加到提供者中,那么它们中的一个总是会出现问题。

【问题讨论】:

    标签: php validation laravel laravel-4


    【解决方案1】:

    手册中也没有明确的信息,但不可能添加多个验证器提供程序Reference on SO

    似乎没有多少人知道它。甚至 unique_with 验证器(我在开头提到的)也只支持注册为提供者。如果我们有另一个供应商验证器也需要注册为服务提供者,那是不可能的。

    所以使用我的textarea_name 验证器的最终解决方案是:

    app/config/app.php 行删除:

    // 'Providers\TextareaNameValidatorServiceProvider',
    

    添加到app/start/global.php:

    Validator::extend('textarea_name', '\Utils\TextAreaNameValidator@validateTextareaName');
    

    并以这种方式定义我的验证器:

    <?php
    
    namespace Utils;
    
    use Validator;
    
    class TextareaNameValidator
    {
        public function validateTextareaName($attribute, $value, $parameters)
        {
            $array = explode(PHP_EOL, trim($value));
    
            if (count($array) !== count(array_unique($array))) {
                return false;
            }
    
    
            foreach ($array as $item) {
                $data['name'] = $item;
    
    
    
                $rules['name']
                    = '
                    required
                    |
                    unique_with:categories, parent = par_cat
                     ';
    
                $validator = Validator::make($data, $rules);
    
                if (!$validator->passes()) {
                    return false;
                }
            }
    
            return true;
        }
    
    }
    

    (注意它不再扩展 Validator 类)

    【讨论】:

      【解决方案2】:

      我注意到错误是:

      validateTextareaname
      

      但你的课是

      validateTextareaName
      

      (注意名称的大写“N”)。

      尝试改变

      $rules['name'] = 'textareaname'; // my custom validator
      

      $rules['name'] = 'textarea_name'; // my custom validator
      

      【讨论】:

      • 感谢您的回复。在你回复之前我注意到了。然而它并不能解决问题。现在我得到Method [validateTextareaName] does not exist. 大写N
      • 我还编辑了我的问题并添加了注册验证器的替代方法,它可以工作,但我不知道为什么服务提供商版本不起作用
      猜你喜欢
      • 2014-10-22
      • 1970-01-01
      • 2014-12-01
      • 2020-01-19
      • 2015-09-12
      • 1970-01-01
      • 2018-03-08
      • 2016-01-08
      • 2016-09-10
      相关资源
      最近更新 更多