如何在PDO(或MySQLi)查询中正确处理关联数组


How do I process an associative array properly in a PDO (or MySQLi) query?

我正在为一个项目使用MySQLi(但可以很容易地切换到PDO,阅读底部的编辑)。我想要的是能够将关联数组处理成mysql查询,而无需手动键入每个键/值对。我知道这可能很简单,但当涉及到MySQLi/PDO时,我仍在学习过程中。为了明确我的意思,这里有一个例子:

假设我有一个关联数组:

$data = array(
    'name' => 'Objective',
    'short_name' => 'OB',
    'generation' => 1
);

我想要的是创建这样一个查询:

UPDATE signals SET ? = ? WHERE sid = '1'

它变成这样的查询(或者代替UPDATE、INSERT、SELECT等):

UPDATE signals SET
    name = 'Objective', 
    short_name = 'OB', 
    generation = 1 
WHERE sid = '1'

所以基本上我的问题是:MySQLi或PDO本身是否可能做到这一点?如果可能的话,我该怎么做?我读过关于在执行之前准备语句的文章,但我还没有意识到这一点。希望有人能帮我。

编辑:我还处于项目的早期阶段,所以我也可以使用PDO,但同样的问题仍然存在。我确实研究了PDO和mysqli,但我也不确定如何使用PDO。因此,为了这个问题,我将把PDO添加到作为标签和问题。

这里有一个函数,它将接受一个输入数组,并产生一些您可以直接放入查询的东西,只要您只更新一个表:

function array_to_pdo_params($array) {
  $temp = array();
  foreach (array_keys($array) as $name) {
    $temp[] = "`$name` = ?";
  }
  return implode(', ', $temp);
}

现在您可以这样执行PDO查询:

// The data
$data = array(
  'name' => 'Objective',
  'short_name' => 'OB',
  'generation' => 1
);
// The parameter for the WHERE clause
$sid = 1;
// Build the query string
$query = "
  UPDATE `signals`
  SET ".array_to_pdo_params($data)."
  WHERE `sid` = ?
";
// Convert the data array to indexed and append the WHERE parameter(s) to it
$queryData = array_values($data);
$queryData[] = $sid;
$stmt = $db->prepare($query); // Obviously add the appropriate error handling
$stmt->execute($queryData);

您可以通过为准备好的查询传递一个输入值数组来使用PDO的execute语句。供参考:http://php.net/manual/en/pdostatement.execute.php

示例:

<?php
/* Execute a prepared statement by passing an array of insert values */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories < :calories AND colour = :colour');
$sth->execute(array(':calories' => $calories, ':colour' => $colour));
?>

Zend_DB将让您做到这一点。

虽然我们在我的作品上做了一个包装,让它变得更简单,但我真的认为它是你能得到的最简单的东西,它为你做了所有神奇的事情。

你真的应该试一试;学习后可以节省大量时间。

如何使用http_build_query构建查询,如下所示:

$columns = array(
  'name',
  'short_name',
  'generation', ...
);
$data = array(
  'name' => 'Objective',
  'short_name' => 'OB',
  'generation' => 1
);
$to_update = array_intersect_key($data, array_flip($columns));
$update_string = urldecode(http_build_query(array_combine(array_keys($columns), array_fill(0, count($columns), '?')), '', ', '));
try {
 $stmt = $db->prepare(sprintf('UPDATE table SET %s WHERE condition=?', $update_string));
 $result = $stmt->execute(array_values($data));
 ...
} catch ('PDOException $ex) { 
}

请确保在$data数组的末尾有WHERE条件的参数。