在Laravel 5.1上验证之前修改输入

时间:2015-08-06 08:29:23

标签: php validation laravel-5 sanitization

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

这是SSHAM\Http\Requests\UserCreateRequest.php

上的Request类
<?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()正在运行,但是当在验证类上处理值时,它尚未被清理。

5 个答案:

答案 0 :(得分:19)

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

重点是,如果您更改规则()功能中的请求值,则对Validator没有任何影响。

您可以通过向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-&gt; all()中的旧值(不受rules()中的更改影响)。

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

更新(L5.5)

如果您使用的是控制器验证功能,您可以执行以下操作:

    $requestData = $request->all();

    // modify somehow
    $requestData['firstname'] = trim($requestData['firstname']);

    $request->replace($requestData);

    $values = $this->validate($request, $rules);

答案 1 :(得分:5)

您可以通过修改请求和设置输入值来执行此操作。

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

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

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

答案 2 :(得分: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;
}

希望这有帮助。

答案 3 :(得分:3)

这些答案在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();
}

答案 4 :(得分:1)

您可以使用prepareForValidation方法

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