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)上工作了。所以抱歉,不知道当前状态:)