Laravel 4:在验证之前修改输入的最佳实践

时间:2014-03-14 08:04:02

标签: php laravel laravel-4

现在,我会像下面的代码一样分别修改每个输入:

$username = trim(Input::get('username'));
$password = trim(Input::get('password'));
$email    = trim(Input::get('email'));

$validator = Validator::make(array('username' => $username, 
                                   'password' => $password, 
                                   'email'    => $email), 
                             array('username' => 'required|min:6', 
                                   'password' => 'required|min:6', 
                                   'email'    => 'email'));

是否有任何方法与

同时进行修剪

Input::all()Input::only('username', 'password', 'email')

这样做的最佳做法是什么?

8 个答案:

答案 0 :(得分:48)

注意: 如果您的任何输入是数组(例如“data []”),此解决方案将无效。 < / p>

你可以试试这个,在验证之前用这一行代码修剪:

Input::merge(array_map('trim', Input::all()));

现在完成剩余的编码

$username = Input::get('username'); // it's trimed 
// ...
Validator::make(...);

如果要从修剪中排除某些输入,则可以使用以下代替all()

Input::except('password');

或者您可以使用

Input::only(array('username'));

更新:由于新的Laravel 5.4.*中间件,TrimStrings输入被裁减。所以,不必担心它,因为这个中间件在每个请求上执行,它也处理数组输入。

答案 1 :(得分:6)

根据您的项目,以下内容可能过于干扰/概括/等等,以满足您的需求;根据需要定制。

  • 我正在利用this小递归数组映射函数来处理输入数组而不会出错。
  • 排除任何名为password的字段(及其确认),因为人们可能希望使用空格作为进一步模糊其密码的一部分。
  • Space在某些类型的文本中具有特殊含义。例如在Markdown中,two or more spaces at the end of a line inserts <br>。虽然你可能在blob的开始或结束时都不需要这个。 YMMV。

<强> app/helpers.php

/**
 * @param callable $callback
 * @param array    $array
 *
 * @return mixed
 *
 * @link http://php.net/manual/en/function.array-map.php#112857
 */
function array_map_recursive($callback, $array)
{
    foreach ($array as $key => $value) {
        if (is_array($array[$key])) {
            $array[$key] = array_map_recursive($callback, $array[$key]);
        } else {
            $array[$key] = call_user_func($callback, $array[$key]);
        }
    }

    return $array;
}

<强> app/filters.php

App::before(
    function (\Illuminate\Http\Request $request) {
        // Trim all input
        $request->merge(
            array_map_recursive(
                "trim",
                array_except(
                    $request->all(),
                    ["password", "password_confirmation"]
                )
            )
        );
    }
);

答案 2 :(得分:3)

也许你可以使用php的array_map函数来修剪输入数组的内容。

$validator = Validator::make(array_map('trim',Input::all()),
                             array('username' => 'required|min:6', 
                                   'password' => 'required|min:6', 
                                   'email'    => 'email'));

或者,如果您想要一个可以在以后使用的变量:

$inputs = array_map('trim', Input::only('username', 'password', 'email'))

答案 3 :(得分:2)

$attributes = Input::only('username', 'password', 'email');

foreach ($attributes as &$value) {
    $value = trim($value);
    //and any further preprocessing you want
}

$validator = Validator::make($attributes, array(
    'username' => 'required|min:6', 
    'password' => 'required|min:6', 
    'email'    => 'email'
));

//now you may pass preprocessed $attributes to the model create() method,
//still having the original input untouched if you may need it

通常,我也会使用此方法在null为空时替换可选值,因为我更喜欢将其作为NULL存储在数据库中,而不是空字符串。

答案 4 :(得分:2)

在模型中而不是在控制器中进行修剪是一种更好的做法,因为这样您就不必在所有控制器中复制代码来反复修剪相同的内容:

public function setUsernameAttribute($value)
{
  $this->attributes['username'] = trim($value);
}

这样,您就不必记住修剪控制器中的任何模型属性。该模型将照顾它,你不必再担心它。

就一次性修剪所有内容而言,我认为差异非常小,没有人会注意到差异。

答案 5 :(得分:0)

以上组合最好。通常,您希望过滤除password和password_confirmation字段之外的所有输入。在过滤器中使用单行进行操作也很不错。

// app / filters.php

App::before(function($request)
{
    // Trim all input
    Input::merge(array_map('trim', Input::except(['password', 'password_confirmation'])));

});

答案 6 :(得分:0)

Halil Özgür代码的改进,以删除所有空格,<br><br ><br class="asdasd">&nbsp

// filters.php
App::before(function (\Illuminate\Http\Request $request) {
    $request->merge(
        array_map_recursive(
            "preg_replace",
            array_except(
                $request->all(),
                ["password", "password_confirmation"]
            )
        )
    );
});

// helpers.php
function array_map_recursive($callback, $array)
{
    foreach ($array as $key => $value) {
        if (is_array($array[$key])) {
            $array[$key] = array_map_recursive($callback, $array[$key]);
        } else {
            $array[$key] = call_user_func_array($callback, ['#(( ){0,}<br( {0,})(/{0,1})>){1,}$#i', '', $array[$key]]);
        }
    }

    return $array;
}

答案 7 :(得分:0)

只需使用sizeTrimStrings中间件。

您不需要做任何额外的事情,因为这些中间件是内置于Laravel 5.4。See this Post

编辑: What if I am not using Laravel 5.4?

  • 让我们从Laravel的Github复制代码。你可以从here
  • 获得
  • 然后确保Laravel知道Kernel.php中的中间件。

    protected $ middleware = [     //以前的中间件     \ APP \ HTTP \中间件\ TrimStrings ::类,     \ APP \ HTTP \中间件\ ConvertEmptyStringsToNull ::类, ];