问:为什么第一种方式没有进行一个参数类型的绑定,那服务器怎么知道传过来的参数是不是合法?
回答:
PHP是若类型语言,无需强制指定数据类型.
用户名,密码这样的参数是否合法,属于业务上的校验.上面的代码只是举例说明PDO防范SQL注入的使用.
图片中的两种写法,并没有本质上的区别. 但第二种写法,更规范些.
-------------------------------------------------------------------
问:为什么通过占位符的一个形式就能实现sql的防注入?
回答:
占位符,可以用冒号: 可以用问号? 这只是表现出来的一种形式. 不仅仅是pdo,更早的mysqli也可以使用类似方式来防范sql注入.
但pdo能够防范sql注入的本质原因是请看我下面的回答:
简单来讲,就是
使用预处理语句 和 参数化查询.
预处理语句和参数分别发送到数据库服务器进行解析,参数将会被当作普通字符处理。
这种方式使得攻击者无法注入恶意的SQL。
sql语句解析的过程:
当你将SQL语句发送给数据库服务器进行预处理和解析时发生了什么?
通过指定占位符(一个?或者一个上面例子中命名的 :username),告诉数据库引擎你想在哪里进行过滤。
当你调用execute的时候,预处理语句将会与你指定的参数值结合。
关键点就在这里:参数的值是和经过解析的SQL语句结合到一起,而不是SQL字符串。
SQL注入是通过触发脚本在构造SQL语句时包含恶意的字符串。
所以,通过将SQL语句和参数分开,从而防止了SQL注入的风险。
任何你发送的参数的值都将被当作普通字符串,而不会被数据库服务器解析。
回到上面的例子,如果$username变量的值为 'zhangsan@xx.com'; DELETE FROM user,那么实际的查询将是在 user表中查找 name 字段值为 'zhangsan@xx.com'; DELETE FROM user 的记录。
这就是神奇之处,可见pdo是将SQL语句模板和变量是分两次发送给MySQL引擎的,
由MySQL引擎完成变量的转义处理,既然变量和SQL模板是分两次发送的,那么就不存在SQL注入的问题了
花了20分钟,码字不易,若对你有帮助,请点赞,谢谢.
若有疑问,请继续追问. 感谢阅读.(*゚∀゚*)