string(10) "-6ren">
gpt4 book ai didi

php - 如何正确创建 PDO 准备的 SQL 语句以使用数组进行 UPDATE

转载 作者:行者123 更新时间:2023-11-29 10:35:12 27 4
gpt4 key购买 nike

我在尝试弄清楚如何在更新现有记录时正确设置准备好的 PDO SQL 语句时迷失了方向。

我的数组被传递到我的方法中是这样的:

array(9) { ["catName"]=> string(10) "Kato Marks" ["age"]=> string(2) "40" ["gender"]=> string(6) "Female" ["createTime"]=> string(19) "2017-10-03 03:55:39" ["coloring"]=> string(5) "Black" ["hairLength"]=> string(5) "Short" ["currentMood"]=> string(5) "rowdy" ["weight"]=> string(2) "17" ["hasCatittude"]=> string(1) "0" }

其中key是数据库表列,value是我要更新的数据库值

到目前为止我有以下内容:

public function updateRow($data, $catID)
{
$db = self::getConnection();

try
{
$stmt = $db->prepare("UPDATE users SET " . implode('= ', array_keys($data). array_values($data)). " WHERE id='{$catID}'");

foreach($data as $key => $value) {
$stmt->bindValue($key, $value, PDO::PARAM_STR);
}
$stmt->execute();
} catch (\PDOException $e) {
return 'Adding new record failed' . $e->getMessage();
}

}

但是当我将语句打印到屏幕上时,我得到以下信息:

PDOStatement Object ( [queryString] => UPDATE users SET WHERE id='108' )

我无法弄清楚如何正确编写准备好的语句,其中我动态地将表名设置为数组键等。任何帮助将不胜感激。

最佳答案

重新评估该方法

根据您的评论,此函数属于 Database 类。诚然,此类可以在任何表上使用,以根据任何条件更新任何行。但是,查看函数签名,我们可以看到它应该接受 $catId 参数,这意味着它将在非常特定的表上使用,使用特定列过滤行。

您可以通过简单地重命名函数和参数以更接近地表示它实际在做什么来解决这个问题,但在我看来,这仍然无法解决问题的核心:该对象有太多职责。

根据Single Responsibility Principle ,一个类“应该有一个,而且只有一个,需要改变的理由”。在这种情况下,如果将一列添加到 User 表中,或者需要将另一列添加到 WHERE 子句中,则仅将 User > 类(或实体)应该受到影响,而Database 类不需要任何更改。

建议

为了简单起见,让我们想象一个 fridge 数据库,其中有一个名为 fruits 的表(我知道,非常有想象力)。

create table fruits (
id int not null auto_increment,
name varchar(20),
color varchar(20),
weight int,
order int, /* order of appearance, say, for a list */
PRIMARY KEY (id)
);

该表的 php 表示可能看起来有点像这样

class Fruit {
private $id;
private $name;
private $color;
private $weight;
private $order;

public function __construct($id, $name, $color, $weight) {
$this->id = $id;
$this->name = $name;
$this->color = $color;
$this->weight = $weight;
$this->order = $order;
}
}

太好了,现在我们有了一个表,以及一个可用于表示该表的记录的对象。现在我们可以添加一个 FruitTable 类,它将充当 Fruit 和数据库本身之间的媒介。

class FruitTable {
private $columns = ['id', 'name', 'color', 'weight', 'order'];
private $table = 'fridge.fruits';
private $conn;

public function __construct($connection) {
$this->conn = $connection
}

public function findOneById($id) {
/**
* Query the DB and hydrate a Fruit instance
*/

return $fruit;
}
}

现在想象一下,我们需要能够根据水果的颜色更改 Fruitorder 字段(我知道,这是我们非常奇怪的事情)正在工作)。没问题,我们可以向 FruitTable 添加一个函数来进行更新。

public function updateOrderByColor($newOrder, $color) {
/* assume proper validation */
$query = $this->conn->prepare("UPDATE fruits SET order = :newOrder WHERE color = :color");
$query->bindParam(':newOrder', $newOrder);
$query->bindParam(':color', $color);

$query->execute();
}

这是一个非常简单的示例,但它显示了通过简单的 Database 类可以获得多大的灵 active 。如果需要添加一列或更改条件,则代码中只有一个位置需要您跳转并进行处理。如果查询出现问题,则只有一个地方可以查找该错误。

这个例子并不完美,FruitTable可能不应该负责直接处理数据库连接。你可以看看如何DoctrineEloquent方法查询构建器,以及它们如何设法将每个类与其余类封装起来。

关于php - 如何正确创建 PDO 准备的 SQL 语句以使用数组进行 UPDATE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46548711/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com