Laravel 4:验证前修剪输入的最佳实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22399326/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel 4 : Best Practice to Trim Input before Validation
提问by Chen-Tsu Lin
Now, I do trim for each input separately like below code:
现在,我像下面的代码一样分别对每个输入进行修剪:
$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'));
Is any approach to do Trim at the same time with
是否有任何方法可以同时进行修剪
Input::all()
or Input::only('username', 'password', 'email')
?
Input::all()
或者Input::only('username', 'password', 'email')
?
And what is the best practice to do this?
这样做的最佳实践是什么?
回答by The Alpha
Note:This solution won't work if any of your inputs are arrays (such as "data[]").
注意:如果您的任何输入是数组(例如“data[]”),则此解决方案将不起作用。
You may try this, trim using this one line of code before validation:
你可以试试这个,在验证之前使用这一行代码修剪:
Input::merge(array_map('trim', Input::all()));
Now do the rest of your coding
现在做剩下的编码
$username = Input::get('username'); // it's trimed
// ...
Validator::make(...);
If you want to exclude some inputs from trimming then you may use following instead if all()
如果你想从修剪中排除一些输入,那么你可以使用以下代替 all()
Input::except('password');
Or you may use
或者你可以使用
Input::only(array('username'));
Update: Since Laravel 5.4.*
inputs are trimmed because of new TrimStrings
middleware. So, no need to worry about it because this middleware executes on every request and it handles array inputs as well.
更新:由于Laravel 5.4.*
新的TrimStrings
中间件,输入被修剪。因此,无需担心,因为此中间件会在每个请求上执行,并且还处理数组输入。
回答by Halil ?zgür
Depending on your project, the below might be too intrusive/generalized/etc for your needs; customize as needed.
根据您的项目,以下内容可能对您的需求过于侵入/概括/等;根据需要定制。
- I'm making use of thislittle recursive array map function in order to process arrays of inputs without error.
- Any field named
password
(and its confirmation) is excluded since people might want to use space as part of further obscuring their passwords. - Space has special meaning in some types of text. For example in Markdown, two or more spaces at the end of a line inserts
<br>
. Though you probably won't need this at the start or at the end of the blob. YMMV.
- 我正在使用这个小的递归数组映射函数来处理输入数组而不会出错。
- 任何命名的字段
password
(及其确认)都被排除在外,因为人们可能希望使用空格作为进一步隐藏密码的一部分。 - 空格在某些类型的文本中具有特殊含义。例如在 Markdown 中,在行尾插入两个或多个空格
<br>
。尽管您可能在 blob 的开始或结束时不需要它。天啊。
app/helpers.php
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/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"]
)
)
);
}
);
回答by Needpoule
Maybe you can use the array_map function of php, to trim the content of your input array.
也许您可以使用 php 的 array_map 函数来修剪输入数组的内容。
$validator = Validator::make(array_map('trim',Input::all()),
array('username' => 'required|min:6',
'password' => 'required|min:6',
'email' => 'email'));
Or if you want a variable you can use later:
或者,如果您想要一个变量,您可以稍后使用:
$inputs = array_map('trim', Input::only('username', 'password', 'email'))
回答by Jake Wilson
It's a better practice to do trimming in the model instead of in controllers because then you don't have to duplicate code in all your controllers to trim the same things over and over:
在模型中而不是在控制器中进行修剪是更好的做法,因为这样您就不必在所有控制器中重复代码来一遍又一遍地修剪相同的东西:
public function setUsernameAttribute($value)
{
$this->attributes['username'] = trim($value);
}
This way, you never have to remember to trim anything model attributes in your controllers. The model will take care of it and you don't have to worry about it ever again.
这样,您永远不必记住在控制器中修剪任何模型属性。该模型会照顾它,您不必再担心它。
As far as trimming everything at once vs. individually, I think the difference is so small that no human would ever notice the difference.
就一次修剪所有内容与单独修剪而言,我认为差异非常小,以至于没有人会注意到差异。
回答by matpop
$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
Usually, I also use this approach to replace optional values with null
when they're empty, because I prefer to store them in DB as NULL
rather than empty strings.
通常,我也使用这种方法在可选值为null
空时替换它们,因为我更喜欢将它们作为NULL
空字符串而不是空字符串存储在数据库中。
回答by omar j
A combination of the above is best. Generally you'll want to filter on all input apart from password and password_confirmation fields. Also doing it with a single line in a filter is nice.
以上的组合是最好的。通常,除了 password 和 password_confirmation 字段之外,您还需要过滤所有输入。在过滤器中使用一行也很好。
// app/filters.php
// 应用程序/过滤器.php
App::before(function($request)
{
// Trim all input
Input::merge(array_map('trim', Input::except(['password', 'password_confirmation'])));
});
回答by MadsonJr
an improvement in Halil ?zgürcode to remove all spaces, <br>
, <br >
, <br class="asdasd">
,  
, etc
改进Halil ?zgür代码以删除所有空格<br>
、<br >
、<br class="asdasd">
、 
、 等
// 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;
}
回答by C.V
Just Use TrimStrings
and ConvertEmptyStringsToNull
Middleware.
只是使用TrimStrings
和ConvertEmptyStringsToNull
中间件。
You do not need to do anything extra, because those middlewares are built-in to Laravel 5.4.See this Post
你不需要做任何额外的事情,因为这些中间件是 Laravel 5.4 内置的。看到这个帖子
Edit: What if I am not using Laravel 5.4?
- Let's copy the code from Laravel's Github. you can get from here
Then make sure that Laravel knows your middlewares in Kernel.php.
protected $middleware = [ // previous middleware \App\Http\Middleware\TrimStrings::class, \App\Http\Middleware\ConvertEmptyStringsToNull::class, ];
- 让我们从 Laravel 的 Github 复制代码。你可以从这里得到
然后确保 Laravel 知道 Kernel.php 中的中间件。
protected $middleware = [ // 以前的中间件 \App\Http\Middleware\TrimStrings::class, \App\Http\Middleware\ConvertEmptyStringsToNull::class, ];