资讯专栏INFORMATION COLUMN

我感觉这是史上最牛的防sql注入方法类

dockerclub / 2433人阅读

摘要:早在年我就开始写这个类库了,平时在工作中,将一些好的想法,一些问题的解决方法等融合进来,历时两年多,经过不断的实践,我感觉它已经很成熟了,于是它来到了你面前我的仓库地址这里假设有一个数据表,其中为主键。

早在2015年我就开始写这个PHP类库了,平时在工作中,将一些好的想法,一些问题的解决方法等融合进来,历时两年多,经过不断的实践,我感觉它已经很成熟了,于是它来到了你面前!

我的仓库地址:https://git.oschina.net/netmo...
这里假设有一个数据表:t_person(id, name, age, sex, addr),其中id为主键。

查询数据:

// 查询ID为5的那行数据的年龄信息:
$age = $pdo->mapField("t-person", array("id"=>5), "age");
//也可以这样(主键作为唯一的条件,字段名可以忽略)
$age = $pdo->mapField("t-person", 5, "age");
// 还可以这样使用原生语句
$age = $pdo->fetchField("select age from t_person where id=5");

// 查询年龄为5的那行数据
$personInfo = $pdo->mapRow("t_person", array("age"=>5));
// 查询ID为5的那行数据(主键作为唯一条件,字段名可省略)
$personInfo = $pdo->mapRow("t-person", 5);
// 查询年龄为5的那行数据,只取id,name两个字段
$personInfo = $pdo->mapRow("t_person", array("age"=>5), array("id", "name"));
// 查询年龄为5且是男性的那行数据,只取id,name两个字段
$personInfo = $pdo->mapRow("t_person", array("age"=>5, sex=>"男"), array("id", "name"));
// 还可以这样使用原生语句
$personInfo = $pdo->fetchRow("select id, age from t_person where age>5 and sex="男"");

// 查询所有年龄为5的数据
$personData = $pdo->mapData("t_person", array("age"=>5));
// 查询所有年龄为5且是男性的数据,只取id,name两个字段
$personData = $pdo->mapData("t_person", array("age"=>5, sex=>"男"), array("id", "name"));
// 条件使用键值对的形式只能表达一种逻辑(即,相等),他在底层上是进行预查询的,是SQL安全的!
// 但有时业务不仅仅是相等的逻辑,如查询年龄大于7的所有数据,为此引入条件模版将拼合的数据部分用双括号括起来,底层使用:key的形式替换并进行预查询
// SQL注入通常是条件数据拼凑以及非法输入造成的,这其中逻辑运算是我们指定的,但数据是外来的,是不可信的,所以要将数据部分多带带用双括号括起来
// 请注意在双引号中使用PHP变量时,正确的写法如:"find_in_set(id,{{{$id_set}}})" ,道理你懂得!
$personData = $pdo->mapData("t_person", array("age>{{7}}"), array("id", "name"));
// 请注意在map开头的这一类方法中,只有条件模版没有指定键值(数字除外),才会对其进行处理,这也是防止误处理的判断(因为此时键值已经没有意义了)
// 有时查询的不仅仅是字段,还可能伴有一些聚合函数及运算,为此引入了查询模版将表达式整体用双括号括起来
// 查询时,字段一般是我们指定的,可以排除SQL注入的可能,故底层没有做特殊处理,所以整体用双括号括起来,告诉底层这是个表达式,而不是字段
// 如查询7岁以上的男性人数
$counter = $pdo->mapRow("t_person", array("age>{{7}}"),array("{{count(sex)}}"));
// 应用条件模版时,模糊查询中的%的位置应当如下(查询名字中有‘王’字的人)
$personData = $pdo->mapData("t_person", array("name like {{%王%}}"), array("id", "name"));

更新数据

// 将ID为5的数据的年龄设置为7
$pdo->mapUpdate("t_person", 5, array("age"=>7));
// 也可以这样(主键作为唯一的条件,名字可以忽略)
$pdo->mapUpdate("t_person", array("id"=>5), array("age"=>7));
// mapUpdate方法不允许空条件出现!
// 通常update 中的set子句都是具体的数据,逻辑简单,所以不支持模版形式

插入数据

// 向t_person表插入一条数据(id自增)
$pdo->postData("t_person", array(

"name"=>"张三",
"age"=>5,
"sex"=>"男",
"addr"=>"大王家村"

));
// 同update 中的set子句一样insert语句不支持模版形式

删除数据

// 删除ID为5的数据
$pdo->mapDelete("t_person", 5);
// 也可以这样(主键作为唯一的条件,名字可以忽略)
$pdo->mapDelete("t_person", array("id"=>5));
// 同更新一样mapDelete方法都不允许空条件出现!

对exec方法扩展,简化‘非查询类’的预查询

// PDO中原生的exec方法只能执行一般的sql,预查询则很麻烦,如查询年龄大于5的人:
$stmt = $pdo->prepare("select * from t_person where age>?");
$count = $stmt->execute(array(5)); // 返回受影响的行数
// 现在你可以将其合并了:
$count = $pdo->exec("update t_person set age=age+1 where age>?", array(5));

对query方法扩展,添加条件模版支持,防止SQL注入

// 进行预查询通常很麻烦,进行查询条件拼凑时更麻烦(如多条件查询,每次的查询条件是跟用户的意愿有关)
// 为此能将一般的查询自动转换为预查询是一个好主意,所以我在query中进行了扩展:
// query($query, $tplCheck=null, $fetchMode=null)
// 当$tplCheck设为true时,会检查SQL语句中是否有条件模版,并自动转换(没有设置时,取决与全局变量$queryTplCheck)
// 使用条件模版自然有稍许的性能损失,如果是类似向数据库中导入信息的操作,还是关掉吧!($tplCheck优先级高于$queryTplCheck)
// 例如查询姓名中含有‘王’字的人,使用条件模版可以这样处理:
$stmt = $pdo->query("select * from t_person where name like {{%{$name}%}}");
// 受 $queryTplCheck 此全局选项影响的方法有fetchField()、fetchRow()、fetchData(),
// 换句话说,它们都支持SQL语句中含有条件模版的写法,因为只有它们底层都调用了query方法!!
// 还有一点需要注意的时,当你开启了$queryTplCheck选项时,你应当将对可预见的字符串类、日期类等数据使用条件模版(默认开启),
// 底层上处理条件模版是进行递归匹配的,并只取最外层‘{{xxxx}}’,但如果你没有进行处理,当用户输入了含‘{{xxxx}}’的数据,就会被错误的处理!
// 如果你处理了,根据取外层的道理,自然就没事了,当然这是一个很小很小的概率事件!!

总结:

通常参数的顺序是表名, 条件, ...;
查询时,注意方法名字是以fetch开头,还是map开头,注意返回的是field、row还是data;
更新和删除操作中的条件部分都可以用条件模版的形式哦!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/22475.html

相关文章

  • 号称史上最牛逼的几篇博客整理(python+java+js等)

    摘要:百度网盘爬虫博客园上如何邀请好友注册您的网站博客园上如何爬取代理服务器博客园上百度图片爬虫开源中国上中文分词十分重要,推荐博客网站真分页代码该怎么写博客园上磁力爬虫源码公开上兼容所有浏览器的浏览器复制问题 号称史上最牛逼的几篇博客这个说法也许夸张了点,但总体来说楼主整理的博客都是楼主幸苦之作,并且都是围绕去转盘网展开,这些博客几乎透漏了该站的所有技术关键,细节,甚至所有核心代码,我个人...

    WrBug 评论0 收藏0
  • 号称史上最牛逼的几篇博客整理(python+java+js等)

    摘要:百度网盘爬虫博客园上如何邀请好友注册您的网站博客园上如何爬取代理服务器博客园上百度图片爬虫开源中国上中文分词十分重要,推荐博客网站真分页代码该怎么写博客园上磁力爬虫源码公开上兼容所有浏览器的浏览器复制问题 号称史上最牛逼的几篇博客这个说法也许夸张了点,但总体来说楼主整理的博客都是楼主幸苦之作,并且都是围绕去转盘网展开,这些博客几乎透漏了该站的所有技术关键,细节,甚至所有核心代码,我个人...

    shenhualong 评论0 收藏0
  • 号称史上最牛逼的几篇博客整理(python+java+js等)

    摘要:百度网盘爬虫博客园上如何邀请好友注册您的网站博客园上如何爬取代理服务器博客园上百度图片爬虫开源中国上中文分词十分重要,推荐博客网站真分页代码该怎么写博客园上磁力爬虫源码公开上兼容所有浏览器的浏览器复制问题 号称史上最牛逼的几篇博客这个说法也许夸张了点,但总体来说楼主整理的博客都是楼主幸苦之作,并且都是围绕去转盘网展开,这些博客几乎透漏了该站的所有技术关键,细节,甚至所有核心代码,我个人...

    shadajin 评论0 收藏0
  • Angular 2.x 从0到1 (一)上最简单的Angular2教程

    摘要:官方支持微软出品,是的超集,是的强类型版本作为首选编程语言,使得开发脚本语言的一些问题可以更早更方便的找到。第一个组件那么我们来为我们的增加一个吧,在命令行窗口输入。引导过程通过在中引导来启动应用。它们的核心就是。 第一节:Angular 2.0 从0到1 (一)第二节:Angular 2.0 从0到1 (二)第三节:Angular 2.0 从0到1 (三) 第一章:认识Angular...

    tuniutech 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<