您的位置:首页 > 其它

关于PDO中prepare方法的探究

2014-01-27 23:01 295 查看
好久没写博文了,这个月事儿真心多,特别是那坑爹的考试,还好全部顺利通过,不然过年都不舒心。

今天在SF上看到一哥们儿问一问题,说他把一数组存进数据库的一个字段,结果出错。对于这个问题,我很久之前探究过,其实没问题,只不过一些细节要稍微注意一下。

在这里我就来说点具体的:

把数组存进数据库,首先能肯定的是存进去的一定是字符串类型。所以只要把数组serialize和unserialize就可以实现存进和取出了。可那哥们儿说他不想用这两个函数实现,于是我就想到了eval函数。

但是对于这个eval函数,还注意:若eval函数执行的是PHP语句,那么要注意分号以及PHP标签的开闭合,这是新手经常出现的错误。

接下来就到了我们说的重点:

如果不用serialize方法的话,我们应该怎样存储数组呢?SF上的那个老兄是这么写的:

array(
\'id\' => \'1\',
);


但是在PDO中,这样的语句,单引号需要转义吗?不是说PDO可以防SQL注入吗?那么PDO不就本身就会对单引号进行转义?一开始我也是这么想的。但是接着自己写了几个demo之后发现,其实不是这样的= . =。于是乎,我感到十分不安,因为在自己之前做的几个项目中,我都没有去验证过PDO这块的SQL注入问题。想当然的就以为PDO会过滤所有的非法字符。

迷茫中,我去查了文档。prepare方法默认是这样执行的:在mysql server接收查询语句前,将占位符替换成实际变量。再把语句发到mysql server。也就是说,事实上还是本地PHP在帮你处理SQL语句。所以本质上和传统的mysql操作函数没什么分别。也就是说,SQL注入该怎么破坏还是能怎么破坏。这道所谓的保护其实并未存在。那到底要怎么写才是安全的呢?PDO提供了一个开关:ATTR_EMULATE_PREPARES,当这个开关为true时,就由本地PHP来处理SQL语句,然后再把语句发往数据库。而如果这个开关的值为false,则PHP不会处理SQL语句,而是把含有占位符的SQL语句及相关变量一起放送往数据库,并由数据库自己来处理。

综上所述,就是说,其实PDO的防SQL注入是从根本上解决问题。同时也说明了为什么用PDO的时候,不需要理会语句中的非法字符。

现在再回到问题上来,SF上的老兄写的代码其实没错——前提是你用的是单引号把array代码包含起来。如果你用的是双引号包含,那就根本不许要理会里面的单引号。

至此,这一个疑问终于解决!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: