【问题标题】:Modify input before validation on Laravel 5.1在 Laravel 5.1 上验证之前修改输入
【发布时间】:2015-10-29 07:09:40
【问题描述】:

我正在尝试在验证成功之前修改用户提交的输入。我关注了this easy instructions,但是当我在 Laravel 5.1 上测试它时,它不起作用。 我做错了吗?

这是我在SSHAM\Http\Requests\UserCreateRequest.php 上的请求课程

<?php

namespace SSHAM\Http\Requests;

use SSHAM\Http\Requests\Request;

class UserCreateRequest extends Request
{

    // Some stuff not related with this problem

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        // Only for debug
        $prova = $this->all();
        echo "<pre>Inside Request - Before sanitize\n[" . $prova['public_key'] . "]</pre>\n";

        // Call a function to sanitize user input
        $this->sanitize();

        // Only for debug    
        $prova = $this->all();
        echo "<pre>Inside Request - After sanitize\n[" . $prova['public_key'] . "]</pre>\n";

        return [
            'username' => 'required|max:255|unique:users',
            'public_key' => 'openssh_key:public',
        ];
    }

    /**
     * Sanitizes user input. In special 'public_key' to remove carriage returns
     */
    public function sanitize()
    {
        $input = $this->all();

        // Removes carriage returns from 'public_key' input
        $input['public_key'] = str_replace(["\n", "\t", "\r"], '', $input['public_key']);

        $this->replace($input);
    }

}

这是我在SSHAM\Providers\OpenSSHKeyValidatorServiceProvider.php 上的自定义验证规则

<?php

namespace SSHAM\Providers;

use Illuminate\Support\ServiceProvider;

class OpenSSHKeyValidatorServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        // Registering the validator extension with the validator factory
        \Validator::extend('openssh_key', function ($attribute, $value, $parameters) {

            // Some stuff not related with this problem    

            // Only for debug
            echo "<pre>Inside Validator value\n[" . $value ."]</pre>\n";
            dd();

            return true;
        });

    }

    // Some stuff not related with this problem    
}

当我调用调试时,我得到了这个输出:

Inside Request - Before sanitize
[blah 
second line 
third line]

Inside Request - After sanitize
[blah second line third line]

Inside Validator value
[blah 
second line 
third line]

似乎sanitize() 正在工作,但是在验证类上处理值时,它还没有被清理。

【问题讨论】:

    标签: php validation laravel-5 sanitization


    【解决方案1】:

    这是一个棘手的问题。我只想出了一种方法来实现你想要的。

    重点是,如果您在 rules() 函数中更改请求值,它对验证器没有影响。

    您可以通过向 UserCreateRequest 添加一个函数来解决问题:

    protected function getValidatorInstance() {
        $this->sanitize();
        return parent::getValidatorInstance();
    }
    

    这会覆盖父级的 getValidatorInstance();

    父级的getValidatorInstance()方法包括

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

    在 rules() 函数中的代码之前到达,因此使用 $this->all() 的旧值(不受 rules() 中的更改影响)。

    如果您在自己的 RequestClass 中覆盖该函数,您可以在调用实际父级的方法之前操作请求值。

    更新(L5.5)

    如果您使用的是控制器验证功能,您可以这样做:

        $requestData = $request->all();
    
        // modify somehow
        $requestData['firstname'] = trim($requestData['firstname']);
    
        $request->replace($requestData);
    
        $values = $this->validate($request, $rules);
    

    【讨论】:

    • 你拯救了我的一天。谢谢!
    【解决方案2】:

    您可以通过修改请求并设置输入值来做到这一点。

    $request->request->set('key', 'value');
    

    或者,如果您更喜欢 request 辅助方法。

    request()->request->set('key', 'value');
    

    【讨论】:

      【解决方案3】:

      如果您使用请求 MyClassRequest 来保持验证,则只需覆盖 Request 类的 all() 方法

      public function all()
      {
          $attributes = parent::all();
      
          //you can modify your inputs here before it is validated
          $attribute['firstname'] = trim($attribute['firstname']);
          $attribute['lastname'] = trim($attribute['lastname']);
      
          return $attributes;
      }
      

      希望这会有所帮助。

      【讨论】:

      • 使用这种方法,您根本不会修改输入值。您只需修改值在 all 方法中的显示方式。虽然这适用于验证规则,但如果您稍后想使用 $request->get('firstname') 访问控制器中的输入字段,您仍将获得未修改的值。这意味着,您得到的值根本没有通过验证器...
      • 我同意,如果我没记错的话,这是我产品中的一段代码,其目的不是修改值,而是对修改后的值进行验证,我认为 OP 在这些行中。为什么我的产品不需要修改值,因为输入中有校验和/哈希,需要在验证后重新计算验证。
      • 如果您在控制器中使用 Input::all()$request-&gt;all(),则值将保持修改状态。
      【解决方案4】:

      这些答案在 5.5 中不再适用于我

      你可以使用

      protected function validationData()
      {
          $this->request->add([
              'SomeField' => '..some code to modify it goes here'
          ]);
          return $this->request->all();
      }
      

      根据请求的 add 方法会覆盖该键的任何现有输入。

      如果你跟随线索,你可以看到为什么这在 Illuminate\Foundation\Http\FormRequest 中有效

      /**
       * Get data to be validated from the request.
       *
       * @return array
       */
      protected function validationData()
      {
          return $this->all();
      }
      

      【讨论】:

      • 帮助其他人修改现有输入:` $this->request->add([ 'some_input' => str_replace("foo", "bar", $this->request->get ('some_input')) ]); `
      【解决方案5】:

      你可以使用prepareForValidation方法

      protected function prepareForValidation() 
      {
          $this->merge(['field' => 'field value' ]) ;
      } 
      

      【讨论】:

        猜你喜欢
        • 2016-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-20
        • 2017-07-19
        相关资源
        最近更新 更多