Php Laravel 4:验证前调整输入的最佳实践

Php Laravel 4:验证前调整输入的最佳实践,php,laravel,laravel-4,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, 'pa

现在,我分别对每个输入进行修剪,如下代码所示:

$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')

这方面的最佳实践是什么

$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
,因为我更喜欢将其存储在DB中,作为
null
,而不是空字符串。

也许您可以使用php的array\u 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'))
注意:如果您的任何输入是数组(例如“数据[]”),则此解决方案将不起作用

您可以尝试此操作,在验证之前使用这一行代码进行修剪:

Input::merge(array_map('trim', Input::all()));
现在完成剩下的编码

$username = Input::get('username'); // it's trimed 
// ...
Validator::make(...);
如果要从修剪中排除某些输入,则如果
all()

或者你可以使用

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

更新:由于新的
TrimStrings
中间件,输入被修剪。因此,无需担心它,因为该中间件会在每个请求上执行,并处理阵列输入。

根据您的项目,下面的内容可能对您的需求来说过于复杂/通用化/etc;根据需要定制

  • 我正在使用一个小的递归数组映射函数来处理输入数组而不会出错
  • 任何名为
    password
    (及其确认)的字段都被排除在外,因为人们可能希望使用空格作为进一步隐藏密码的一部分
  • 在某些类型的文本中,空间具有特殊的意义。例如,在降价中。虽然在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::before(
    function (\Illuminate\Http\Request $request) {
        // Trim all input
        $request->merge(
            array_map_recursive(
                "trim",
                array_except(
                    $request->all(),
                    ["password", "password_confirmation"]
                )
            )
        );
    }
);
app/filters.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::before(
    function (\Illuminate\Http\Request $request) {
        // Trim all input
        $request->merge(
            array_map_recursive(
                "trim",
                array_except(
                    $request->all(),
                    ["password", "password_confirmation"]
                )
            )
        );
    }
);

以上两者的结合是最好的。通常,除了密码和密码确认字段外,您还需要对所有输入进行筛选。在过滤器中使用一行代码也很好

//app/filters.php

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

});

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

public function setUsernameAttribute($value)
{
  $this->attributes['username'] = trim($value);
}
这样,您就不必记住修剪控制器中的任何模型属性。模型会处理好它,你再也不用担心它了

就一次修剪与单独修剪而言,我认为差异非常小,以至于没有人会注意到差异。

删除所有空格的代码改进,



,等等

// 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;
}
//filters.php
App::before(函数(\light\Http\Request$Request){
$request->merge(
数组\映射\递归(
“preg_replace”,
数组_除外(
$request->all(),
[“密码”、“密码确认”]
)
)
);
});
//helpers.php
函数数组\u映射\u递归($callback,$array)
{
foreach($key=>$value的数组){
if(是_数组($array[$key])){
$array[$key]=数组映射递归($callback,$array[$key]);
}否则{
$array[$key]=call_user_func_array($callback,['#(((){0,}){1,}$#i',''.$array[$key]]);
}
}
返回$array;
}

只需使用
TrimStrings
convertEmptyStringsToull
中间件即可

您不需要做任何额外的事情,因为这些中间件内置于Laravel5.4中

编辑:

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

    受保护的$中间件=[ //以前的中间件 \App\Http\Middleware\TrimStrings::class, \App\Http\Middleware\ConvertEmptyStringsToull::类, ];


您可以这样做:这意味着我需要在验证之前对新用户执行
操作?现在我在验证后使用
User::create()
。是否要从密码中删除空格?很好,但我认为最好分配一个变量,以后可以与
User::create()
一起重用。究竟
input::merge()
做什么?我在官方文件中找不到它。它将新的输入与旧的输入合并。但是在这里,它用修剪输入替换输入,因为arra_map返回另一个修剪输入数组。回答得好。添加一条线,就像在前端修剪一样!谢谢~在使用数组参数(如
)时不起作用。您想将此因素考虑到模型中,但为什么要让模型承担控制器的责任?我的意思是,在OP案例中,他的控制者负责清理输入数据。@Alexandre Martini控制者应该只负责接受请求和返回响应。提问者有Laravel 4.x,而不是5.4。但是,是的,因为5.4,这是可能的。所以我不会投反对票。因此,对于5.3(大型项目),我必须坚持使用过滤器版本?在Laravel4中,您可以复制到您的中间件目录。并在您的路线中使用。是的,您可以但不应该混合使用不同版本的类。;-)也许它“起作用”,但由于上述原因,它通常不是一个好主意。您还可以通过使用实用程序类(重新运行
composer dump autoload
!)来避免使用函数(周围没有对象/类)。例如,假设
Arrays.php
包含用于数组操作的实用程序类,则将它们放置在
app\libraries\Arrays.php
中。再多一点哦。:-)也许可以考虑添加类型提示。还是Laravel 4没有在PHP5或更高版本上运行?@Roland如果这是针对我的:老实说,我已经多年没有在Laravel(或PHP)上工作了。所以抱歉,不知道当前状态:)