PHP实现数组的白名单过滤
usernumber
,username
,password
等等,将这些拼装成了一个数组,并将其作为参数,传给model
层并写入数据库。比如:
在控制器中拼装了如下参数:
$params = [
'number' => 1001,
'username' => 'kirineko',
'password' => '123456',
'school' => 'cmu',
];
Model\User::insert($params);
在模型层中写了一个insert
方法:
public static insert($params)
{
$ins = new self();
foreach($params as $key => $value) {
$ins->{$key} = $value;
}
$ins->save();
}
但是目前的问题在于,如果我在传递参数时,传递的数组索引,在数据库中并没有,比如上述传递的school
,在数据库中就并没有这个字段;并比如数据库中需要传入age
的值,上述数据中却并没有传递。上述这些情况都会造成数据库写入失败。
现在我的解决方案是,在insert方法中,对传入的数据参数进行过滤,方法如下:
public static insert($params) {
$ins = new self();
$filters = ['number','username','password','age'];
$real_params = [];
foreach ($filters as $filter) {
if(isset($params[$filter])) {
$invite_params[$filter] = $params[$filter];
}
}
foreach($invite_params as $key => $value) {
$ins->{$key} = $value;
}
$ins->save();
}
通过过滤,把数组中合法的输入赋给了另外一个数组。但是这种方法是在是太麻烦了。请问有没有更好的方法实现这个功能呢?
回复内容:
在PHP中,经常会将数组作为参数进行传递;现在的一个需求是,首先Web程序从Request中获取到了一些参数,比如usernumber
,username
,password
等等,将这些拼装成了一个数组,并将其作为参数,传给model
层并写入数据库。比如:
在控制器中拼装了如下参数:
$params = [
'number' => 1001,
'username' => 'kirineko',
'password' => '123456',
'school' => 'cmu',
];
Model\User::insert($params);
在模型层中写了一个insert
方法:
public static insert($params)
{
$ins = new self();
foreach($params as $key => $value) {
$ins->{$key} = $value;
}
$ins->save();
}
但是目前的问题在于,如果我在传递参数时,传递的数组索引,在数据库中并没有,比如上述传递的school
,在数据库中就并没有这个字段;并比如数据库中需要传入age
的值,上述数据中却并没有传递。上述这些情况都会造成数据库写入失败。
现在我的解决方案是,在insert方法中,对传入的数据参数进行过滤,方法如下:
public static insert($params) {
$ins = new self();
$filters = ['number','username','password','age'];
$real_params = [];
foreach ($filters as $filter) {
if(isset($params[$filter])) {
$invite_params[$filter] = $params[$filter];
}
}
foreach($invite_params as $key => $value) {
$ins->{$key} = $value;
}
$ins->save();
}
通过过滤,把数组中合法的输入赋给了另外一个数组。但是这种方法是在是太麻烦了。请问有没有更好的方法实现这个功能呢?
使用 ORM
吧,骚年!
ORM:不管你传入多少字段,我只 插入 | 更新
咱俩的 交集字段
。
不需要的school为什么要传进去……
写个私有属性, 比如$_allow, 再来个私有属性$_requiere,allow 就是允许的字段, require 是必须的字段,每次curd 的时候,把要操作的字段和 allow比较一下,用 array_diff,如果有不同的字段 ,throw 一个 exception,貌似以前大家都是这么干的吧 , 先进点的去看 tp, 或者是 yii2,因为你的问题,如果用框架的话是不用考虑的,框架已经都帮你弄好了,你用框架提供的方法就可以了
通常这个东西是这样处理的,如果一个对象是一个数据表的映射的话,那么它在初始化的时候会去读取数据表的结构,但是如果每次都加载表结构影响性能,所以会把表结构信息缓存起来,即总是从缓存加载数据表结构,同时提供一个专门的功能用来清除该缓存。
这些表结构信息可以:
1- 通过字段名实现数据过滤
2- 实现简单的有效性检查,如非空检查、数字检查、长度检查等
3- 表单辅助生成等
可以把数据表字段列表查出来
mysql> select COLUMN_NAME from information_schema.`COLUMNS` where TABLE_NAME='XXX';
你这种处理方法, 低效且不安全, 建议使用 ORM 的方案.
写个辅助函数处理 PHP高级过滤器