【问题标题】:How do I report every field's validation errors in Laravel?如何在 Laravel 中报告每个字段的验证错误?
【发布时间】:2017-01-07 20:02:24
【问题描述】:

我正在将验证转移到模型中(watson/validating 包)。但有些验证规则不能移动。例如,考虑用户注册表单。您希望强制密码不少于 6 个字符。你不能在模型中这样做,因为在模型中你有密码的哈希值。

但是,如果您的密码未能通过控制器验证规则,则只会报告来自控制器验证的错误。我显然希望用户看到controllermodel 验证的结果。

【问题讨论】:

  • 在什么情况下你需要两者?这个想法对我来说似乎是多余的。
  • @ErikBerkun-Drevnig 我没有描述过吗?通常,您希望在模型中进行验证,而不是在每次创建模型时都重复它。但是模型中不能执行最小长度密码验证,因为模型中有哈希,而不是密码本身。
  • 我的意思是,通常您放入模型的数据来自控制器,因此请求验证就足够了。当值本身已经验证时,您会在什么情况下验证模型?
  • 就像我说的,不要重复验证规则。例如,您有一个表单来创建具有基本字段集的对象。稍后,用户可以按编辑并更改基本+一些额外的字段。此外,测试模型通常比测试控制器更快/更容易。
  • 是的,所以在这种情况下,您可以创建一个表单请求对象 laravel.com/docs/5.3/validation#form-request-validation 并将其用于创建和编辑表单。

标签: php laravel validation


【解决方案1】:

我建议将Form Request objectsdatabase constraints 结合使用。这样,您可以从控制器中提取表单验证,并在字段相似的情况下将它们重用于多个请求。

这将防止用户将不正确的数据输入您的数据库,但与您尝试在模型上进行的验证不同,如果其他开发人员忽略使用正确的验证对象,它不会阻止将数据插入数据库。数据库约束可以解决其中的一些问题,但您所描述的不是框架的一部分。

祝你好运!

【讨论】:

    【解决方案2】:

    这是我想出的:

    class RegisterController extends Controller
    {
        protected function validator(array $data)
        {
            $rules = merge_validation_rules((new User)->getRules(), [
                'email' => 'required',
                'password' => 'min:6',
            ]);
            return Validator::make($data, $rules);
        }
        ...
    

    merge_validation_rules助手:

    function merge_validation_rules($a, $b)
    {
        $r = $a;
        foreach ($b as $k => $v)
            if (isset($a[$k])) {
                $r[$k] = array_merge(explode('|', $a[$k]), explode('|', $b[$k]));
                if (in_array('sometimes', $r[$k])
                && in_array('required', $r[$k]))
                    $r[$k] = array_diff($r[$k], ['sometimes']);
                $r[$k] = implode('|', $r[$k]);
            } else
                $r[$k] = $b[$k];
        return $r;
    }
    

    merge_validation_rules测试:

    <?php
    
    namespace Tests;
    
    use Tests\TestCase;
    
    class HelpersTest extends TestCase
    {
        /**
         * @dataProvider mergeValidationRulesProvider
         */
        function testMergeValidationRules($input, $output)
        {
            $r = call_user_func_array('merge_validation_rules', $input);
    
            $this->assertEquals($output, $r);
        }
        function mergeValidationRulesProvider() { return [
            [[['a' => 'ra1', 'b' => 'rb1'], ['a' => 'ra2', 'c' => 'rc1']],
                ['a' => 'ra1|ra2', 'b' => 'rb1', 'c' => 'rc1']],
            [[['a' => 'sometimes'], ['a' => 'required']],
                ['a' => 'required']],
        ]; }
    }
    

    在这里您可以看到另一个问题。我同时使用用户/密码和社交登录。所以电子邮件并不总是存在(不是每个社交网络都会返回它)。所以在模型中我有'email' =&gt; 'sometimes|email',但在注册控制器中我希望它是required。现在,如果存在 required,我将删除 sometimes。我们会看看它是否会成功。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-10
      • 1970-01-01
      • 1970-01-01
      • 2017-07-27
      • 1970-01-01
      • 2017-11-26
      • 1970-01-01
      相关资源
      最近更新 更多