Php 如何将动态构造的ext/mysql查询转换为PDO准备的语句?

Php 如何将动态构造的ext/mysql查询转换为PDO准备的语句?,php,mysql,pdo,Php,Mysql,Pdo,我正在将一些使用ext/mysql(mysql_*()函数)的代码转换为PDO和准备好的语句。以前,当我动态构造查询时,我只是通过mysql\u real\u escape\u string()传递字符串,并将它们直接放入查询中,但现在我发现在执行查询时需要将值作为数组传递,或者在执行前绑定变量 如何将我的旧代码转换为使用新的数据库驱动程序?将查询从ext/mysql迁移到PDO准备的语句需要在许多方面采用新的方法。这里我将介绍一些经常需要执行的常见任务。这并不是对每种可能的情况都进行详尽的匹配

我正在将一些使用ext/mysql(
mysql_*()
函数)的代码转换为PDO和准备好的语句。以前,当我动态构造查询时,我只是通过
mysql\u real\u escape\u string()
传递字符串,并将它们直接放入查询中,但现在我发现在执行查询时需要将值作为数组传递,或者在执行前绑定变量


如何将我的旧代码转换为使用新的数据库驱动程序?

将查询从ext/mysql迁移到PDO准备的语句需要在许多方面采用新的方法。这里我将介绍一些经常需要执行的常见任务。这并不是对每种可能的情况都进行详尽的匹配,只是为了演示动态生成查询时可以使用的一些技术

在我们开始之前,有几件事要记住——如果有些事情不正常,在提问之前检查一下这个列表

  • 如果不显式禁用模拟准备,您的查询并不比使用
    mysql\u real\u escape\u string()更安全。
    。我需要一个完整的解释
  • 在单个查询中不能混合使用命名占位符和问号占位符。在开始构造查询之前,必须决定使用另一个查询,不能中途切换
  • 预制语句中的占位符只能用于值,不能用于对象名称。换句话说,您不能使用占位符动态指定数据库、表、列或函数名或任何SQL关键字。通常,如果您发现需要这样做,那么应用程序的设计是错误的,您需要重新检查它
  • 用于指定数据库/表/列标识符的任何变量都不应直接来自用户输入。换句话说,不要使用
    $\u POST
    $\u GET
    $\u COOKIE
    或任何其他来自外部源的数据来指定列名。在使用此数据构造动态查询之前,应该对其进行预处理
  • PDO命名占位符在查询中指定为
    :name
    。当传入数据以执行时,相应的数组键可以选择性地包括前导的
    ,但这不是必需的。占位符名称应仅包含字母数字字符
  • 命名占位符在查询中不能使用多次。要多次使用相同的值,必须使用多个不同的名称。如果您有一个具有许多重复值的查询,请考虑使用问号占位符。
  • 使用问号占位符时,传递值的顺序很重要。还必须注意占位符位置是1索引的,而不是0索引的
下面的所有示例代码都假定已经建立了数据库连接,并且相关的PDO实例存储在变量
$db


将关联数组用作列/值列表 最简单的方法是使用命名占位符

使用ext/mysql,可以在构造查询时转义值,并将转义值直接放入查询中。在构造PDO准备好的语句时,我们使用数组键来指定占位符名称,因此可以将数组直接传递给
PDOStatement::execute()

对于本例,我们有一个包含三个键/值对的数组,其中键表示列名,值表示列的值。我们希望选择任何列匹配的所有行(数据具有
关系)

//要用于字段列表的数组
$data=数组(
'field1'=>'value1',
'field2'=>'value2',
“field3'=>“value3”
);
//将字段保持在中间状态的临时数组
$whereClause=array();
//迭代数据并转换为单个子句元素
foreach($key=>$value形式的数据){
$whereClause[]=“`$key`=:$key”;
}
//构造查询
$query='1
挑选*
从`表\名称`
WHERE'.内爆('OR',$whereClause)。'
';
//准备查询
$stmt=$db->prepare($query);
//执行查询
$stmt->execute($data);

使用数组为()
子句中的
构造值列表
实现这一点的最简单方法是使用问号占位符

这里我们有一个由5个字符串组成的数组,我们希望与给定的列名进行匹配,并返回列值至少与5个数组值中的一个匹配的所有行

//值的数组
$data=数组(
“值1”,
“价值2”,
“价值3”,
“价值4”,
“价值5”
);
//构造一个与值数组长度相等的问号数组
$placeHolders=数组填充(0,计数($data),“?”);
//对数组进行规格化,使其为1索引
数组_unshift($data,”);
未设置($data[0]);
//构造查询
$query='1
挑选*
从`表\名称`
其中,`field`位于('.intlode(',',$placeHolders)。'))
';
//准备查询
$stmt=$db->prepare($query);
//执行查询
$stmt->execute($data);
如果您已经确定要使用带有命名占位符的查询,那么该技术会稍微复杂一些,但不会太复杂。只需在数组上循环,即可将其转换为关联数组并构造命名占位符

//值的数组
$data=数组(
“值1”,
“价值2”,
“价值3”,
“价值4”,
“价值5”
);
//用于保存数据的临时数组
$placeHolders=$valueList=array();
//循环数组并构造命名格式
对于($i=0,$count=count($data);$i<$count;$i++){
$placeHolders[]=“:列出$i”;
$valueList[“list$i”]=$data[$i];
}
//构造查询
$query='1
挑选*
从`表\名称`
其中,$field`位于(')。内爆(',',$占位符