两段PHP数据库插入代码:一段报错一段正常,求问题原因
为什么第一段PDO插入代码报错,第二段正常运行?
这个问题的核心在于SQL语句的参数化处理方式,咱们一步步拆解来聊:
第一段代码的问题根源
第一段代码是直接把PHP变量$phone_1、$phone_2、$phone_3硬拼进了SQL字符串里:
// 无法运行 $stmt = $connection->prepare( "INSERT INTO numbers (homePhone, mobilePhone, officePhone)". " VALUES ($phone_1,$phone_2,$phone_3)"); $stmt->execute();
当这段代码执行时,PDO会把拼接后的完整SQL直接发给数据库服务器解析。举个实际例子,如果$phone_1的值是blablabla,最终生成的SQL会是这样:
INSERT INTO numbers (homePhone, mobilePhone, officePhone) VALUES (blablabla, xxx, yyy)
数据库看到blablabla没有被引号包裹,会默认把它当成一个列名来处理,但你的numbers表里根本不存在叫blablabla的列,自然就抛出了no such column: blablabla的错误。
而且这种写法还有个致命问题——SQL注入风险,如果变量里被传入恶意SQL代码,直接拼接会直接威胁数据库安全。
第二段代码的正确逻辑
第二段用了PDO的预处理语句(占位符参数绑定),这才是操作数据库的标准姿势:
// 可以运行 $stmt = $connection->prepare( "INSERT INTO numbers (homePhone, mobilePhone, officePhone)". " VALUES (?,?,?)"); $stmt->execute([$phone_1, $phone_2, $phone_3]);
这里的?是占位符,PDO会先把带占位符的SQL发给数据库完成编译,等到execute时再把变量值作为参数传递进去。数据库会自动处理值的引号包裹和特殊字符转义,最终生成的合法SQL会是:
INSERT INTO numbers (homePhone, mobilePhone, officePhone) VALUES ('blablabla', 'xxx', 'yyy')
这样既避免了把值误判为列名的语法错误,又彻底杜绝了SQL注入风险,还能复用编译后的SQL提升执行效率。
总结来说:直接拼接变量到SQL里是错误且危险的写法,使用预处理语句的占位符才是PDO操作数据库的正确方式。
内容的提问来源于stack exchange,提问作者user9670600
相关产品推荐
相关产品推荐

