PDO::ATTR_EMULATE_PREPARES

PDO::ATTR_EMULATE_PREPARES属性设置为false引发的血案

无人久伴 提交于 2020-01-07 12:14:07
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 前段时间给pdo设置了下emulate_prepare属性,引发了这次的血案。 在这记录下事情的经过,没准大家能避免同样的错误。 先说以下环境。php 5.2.5,mysql 5.0.81,服务器使用的GBK编码。 起因 首先是看到一个报错信息,说是sql语句的syntax error。这里给一个能重现的例子。报错的位置就是在红框的位置。 排查 从上面看,看不出语法错误。然而GBK编码的“玕”字后一个字节是0x5c,跟“\”一样。看到这,是不是就觉得这可能会有问题?但是,我记得我们是使用了pdo的prepare这种方式的(上面sql语句中我使用实际的值代替了?占位符),即使这个汉子特殊,也不会报语法错误才对。于是我翻了翻代码,发现,果然没有显示的设置PDO::ATTR_EMULATE_PREPARES属性的值。而默认是设置为true的(从字面意思就能理解,模拟prepare,不是真正意义上的prepare执行方式)。 使用tcpdump抓包,wireshark查看,确定了一下,发现果然是上面这样。 抓包的结果, 0xab5c是汉字玕的GBK编码。这里看到的是,pdo模拟处理后,多加了一个'\',而在这之前,已经告诉mysql server,客户端使用的是GBK编码(set names gbk),mysql