PHP 并清理字符串以用于动态创建的 DB2 查询
PHP and sanitizing strings for use in dynamicly created DB2 queries
我对 IBMi 的 DB2 比较陌生,想知道如何在 PHP 中为动态生成的查询正确清理数据的方法。
例如,如果编写一个 PHP class 来处理所有数据库交互,则必须传递 table 名称等,其中一些不能使用 [=11 传递=]. db2_prepare()
是否自行清理结构化查询?或者是否有可能在 db2_prepare()
调用中 "executed" 出现格式错误的查询?我知道有 db2_execute()
但数据库在 db2_prepare()
中做了一些事情,我不确定是什么(只是语法验证?)。
我知道如果传递的值绝不会受到用户输入结果的影响,那应该不是什么大问题,但是如果有人想在查询中使用数据之前清理数据(不使用 db2_prepare()/db2_execute()
) db2 的清单是什么?我唯一能找到的就是通过在单引号前加上另一个单引号来转义单引号。真的只需要注意这些吗?
当您调用 db2_prepare()
时并没有神奇的 "cleansing" 发生——它只会尝试将您传递的字符串编译为单个 SQL 语句。如果它不是有效的 DB2 SQL 语句,将返回错误。与 db2_exec()
相同,只是它会在一次调用中执行 db2_prepare()
和 db2_execute()
分别执行的操作。
编辑(以解决来自 OP 的更多问题)。
每个 SQL 语句的执行分为三个阶段:
编译(或准备),在解析语句时,进行句法语义分析,确定用户权限,创建语句执行计划。
参数绑定 -- 一个可选步骤,仅当语句包含参数标记时才需要。在此阶段,将根据准备验证每个参数数据类型以匹配语句文本预期的内容。
Execution proper,当数据库引擎执行步骤1生成的查询计划时,可选地使用步骤2提供的参数(变量)值。语句结果,如果有的话,然后返回给客户端。
db2_prepare()
、db2_bind_param()
、db2_execute()
分别对应步骤1、2、3。 db2_exec()
结合步骤 1 和 3,跳过步骤 2 并假设没有参数标记。
现在,谈到参数安全,绑定步骤确保提供的参数值符合预期的数据类型约束。例如,在包含类似 ...WHERE MyIntCol = ?
的查询中,如果我尝试将字符值绑定到该参数,它将生成错误。
如果我改为使用 db2_exec()
并编写如下语句:
$stmt = "SELECT * FROM MyTab WHERE MyIntCol=" . $parm
我可以轻松地将 "0 or 1=1"
之类的东西作为 $parm
的值传递,这将生成一个完全有效的 SQL 语句,只有这样才能成功解析、准备和执行db2_exec()
。
我对 IBMi 的 DB2 比较陌生,想知道如何在 PHP 中为动态生成的查询正确清理数据的方法。
例如,如果编写一个 PHP class 来处理所有数据库交互,则必须传递 table 名称等,其中一些不能使用 [=11 传递=]. db2_prepare()
是否自行清理结构化查询?或者是否有可能在 db2_prepare()
调用中 "executed" 出现格式错误的查询?我知道有 db2_execute()
但数据库在 db2_prepare()
中做了一些事情,我不确定是什么(只是语法验证?)。
我知道如果传递的值绝不会受到用户输入结果的影响,那应该不是什么大问题,但是如果有人想在查询中使用数据之前清理数据(不使用 db2_prepare()/db2_execute()
) db2 的清单是什么?我唯一能找到的就是通过在单引号前加上另一个单引号来转义单引号。真的只需要注意这些吗?
当您调用 db2_prepare()
时并没有神奇的 "cleansing" 发生——它只会尝试将您传递的字符串编译为单个 SQL 语句。如果它不是有效的 DB2 SQL 语句,将返回错误。与 db2_exec()
相同,只是它会在一次调用中执行 db2_prepare()
和 db2_execute()
分别执行的操作。
编辑(以解决来自 OP 的更多问题)。
每个 SQL 语句的执行分为三个阶段:
编译(或准备),在解析语句时,进行句法语义分析,确定用户权限,创建语句执行计划。
参数绑定 -- 一个可选步骤,仅当语句包含参数标记时才需要。在此阶段,将根据准备验证每个参数数据类型以匹配语句文本预期的内容。
Execution proper,当数据库引擎执行步骤1生成的查询计划时,可选地使用步骤2提供的参数(变量)值。语句结果,如果有的话,然后返回给客户端。
db2_prepare()
、db2_bind_param()
、db2_execute()
分别对应步骤1、2、3。 db2_exec()
结合步骤 1 和 3,跳过步骤 2 并假设没有参数标记。
现在,谈到参数安全,绑定步骤确保提供的参数值符合预期的数据类型约束。例如,在包含类似 ...WHERE MyIntCol = ?
的查询中,如果我尝试将字符值绑定到该参数,它将生成错误。
如果我改为使用 db2_exec()
并编写如下语句:
$stmt = "SELECT * FROM MyTab WHERE MyIntCol=" . $parm
我可以轻松地将 "0 or 1=1"
之类的东西作为 $parm
的值传递,这将生成一个完全有效的 SQL 语句,只有这样才能成功解析、准备和执行db2_exec()
。