我正在将一些使用ext / mysql(mysql_*()
函数)的代码转换为PDO和预处理语句。以前当我动态构建查询时,我只是通过mysql_real_escape_string()
传递我的字符串并将它们直接放入我的查询中,但现在我发现我需要在执行查询时将值作为数组传递,或绑定变量在执行之前。
如何将旧代码转换为使用新数据库驱动程序?
答案 0 :(得分:15)
将查询从ext / mysql迁移到PDO预处理语句需要一种新方法来实现多个方面。在这里,我将介绍一些经常需要执行的常见任务。这并不是穷举所有可能的情况,它只是为了演示动态生成查询时可以采用的一些技术。
在我们开始之前,需要记住一些事项 - 如果某些事情无法正常工作,请在提问前查看此列表!
mysql_real_escape_string()
更安全。 See this获得完整的解释。$_POST
,$_GET
,$_COOKIE
或来自外部来源的任何其他数据来指定列名。在使用它构建动态查询之前,您应该预先处理这些数据。:name
。传递数据以供执行时,相应的数组键可以选择包含前导:
,但不是必需的。占位符名称应仅包含字母数字字符。下面的所有示例代码都假定已建立数据库连接,并且相关的PDO实例存储在变量$db
中。
最简单的方法是使用命名占位符。
使用ext / mysql,可以在构造查询时转义值,并将转义值直接放入查询中。在构造PDO预处理语句时,我们使用数组键来指定占位符名称,因此我们可以将数组直接传递给PDOStatement::execute()
。
对于此示例,我们有一个包含三个键/值对的数组,其中键表示列名,值表示列的值。我们希望选择任何列匹配的所有行(数据具有OR
关系)。
// The array you want to use for your field list
$data = array (
'field1' => 'value1',
'field2' => 'value2',
'field3' => 'value3'
);
// A temporary array to hold the fields in an intermediate state
$whereClause = array();
// Iterate over the data and convert to individual clause elements
foreach ($data as $key => $value) {
$whereClause[] = "`$key` = :$key";
}
// Construct the query
$query = '
SELECT *
FROM `table_name`
WHERE '.implode(' OR ', $whereClause).'
';
// Prepare the query
$stmt = $db->prepare($query);
// Execute the query
$stmt->execute($data);
IN (<value list>)
子句的值列表实现这一目标的最简单方法是使用问号占位符。
这里我们有一个包含5个字符串的数组,我们想要匹配给定的列名,并返回列值与5个数组值中至少有一个匹配的所有行。
// The array of values
$data = array (
'value1',
'value2',
'value3',
'value4',
'value5'
);
// Construct an array of question marks of equal length to the value array
$placeHolders = array_fill(0, count($data), '?');
// Normalise the array so it is 1-indexed
array_unshift($data, '');
unset($data[0]);
// Construct the query
$query = '
SELECT *
FROM `table_name`
WHERE `field` IN ('.implode(', ', $placeHolders).')
';
// Prepare the query
$stmt = $db->prepare($query);
// Execute the query
$stmt->execute($data);
如果您已经确定要使用带有命名占位符的查询,则该技术会稍微复杂一些,但不会太多。您只需循环遍历数组以将其转换为关联数组并构造命名占位符。
// The array of values
$data = array (
'value1',
'value2',
'value3',
'value4',
'value5'
);
// Temporary arrays to hold the data
$placeHolders = $valueList = array();
// Loop the array and construct the named format
for ($i = 0, $count = count($data); $i < $count; $i++) {
$placeHolders[] = ":list$i";
$valueList["list$i"] = $data[$i];
}
// Construct the query
$query = '
SELECT *
FROM `table_name`
WHERE `field` IN ('.implode(', ', $placeHolders).')
';
// Prepare the query
$stmt = $db->prepare($query);
// Execute the query
$stmt->execute($valueList);