PHP:准备PDO数据库语句的一种更简洁的方法?

时间:2013-11-25 11:28:33

标签: php mysql pdo

我对PDO准备好的陈述相对较新。

我不禁觉得必须有一种更简单,更简洁的方法来执行以下操作:无论如何我将所有内容加载到数组中,然后必须将整个内容重写为一组':blah '=> $ found ['blah'] 废话。

在下面做什么是更简洁的方式?

$stmt = $db->prepare("UPDATE googleplay SET name=:name, releasedate=:releasedate, version=:version, image=:image, url=:url, rating=:rating WHERE id=:id");
$stmt->execute(array(   
    ':id'=>$found['id'],
    ':name'=>$found['name'],
    ':releasedate'=>$found['releasedate'],
    ':version'=>$found['version'],
    ':image'=>$found['image'],
    ':url'=>$found['url'],
    ':rating'=>$found['rating']
    ));

4 个答案:

答案 0 :(得分:4)

您不需要在密钥名称前加上:,它也可以不用。所以:

$stmt->execute($found);

即使您必须这样做,也要自动执行:

$found = array_combine(array_map(function ($key) { return ":$key"; }, array_keys($found)), $found);

答案 1 :(得分:2)

在PDO文档中还有其他方法可以做到这一点,有些则不是。你可以编写一个php函数来为你做这个,使它更整洁。

同样的功能也允许使用?来表示基础。对于许多一次性查询,它更清晰。

然而,最重要的是使用ORM(对象关系映射器),例如Doctrine或任意数量的ActiveRecord克隆(例如Laravel)。

答案 2 :(得分:0)

$allowed = array('name', 'releasedate', 'version', 'image', 'url', 'rating');
$sql = "UPDATE users SET ".pdoSet($allowed, $values, $found)." WHERE id = :id";
$stm = $dbh->prepare($sql);
$values["id"] = $found['id'];
$stm->execute($values);

其中pdoSet()是一个从提供的数组中生成SET语句的函数(对允许的字段列表检查输入数组)

但是,最好的方法是实现另一种类型的占位符,这将使您的代码成为世界上最好的代码:

$db->query("UPDATE users SET ?u WHERE id = ?i", $found, $id);

假设$found已经过验证(意味着不是来自用户输入,而是硬编码或过滤掉)并且$id不是数组的一部分。

答案 3 :(得分:0)

// a closure that, given a key, returns a SET subclause for an UPDATE statement
$cl_set = function($k) {
  if (!preg_match('/^[[:alnum:]_]+$/', $k))
    throw new Exception('Key cannot be used as a placeholder name');
  return "$k = :$k";
};

// use our closure to generate the SQL
$stmt = $db->prepare(
  'UPDATE googleplay SET ' . implode(', ', array_map($cl_set, array_keys($found)))
);

// execute - this works because of the observation in @deceze's answer:
$stmt->execute($found);