如何在PHP中动态更新表

时间:2012-02-08 12:08:14

标签: php sql

我正在构建一个应用程序,用户可以在其中添加,编辑和删除数据库中的用户。

我已经完成了'查看用户'(选择语句返回已连接的表)和'添加用户'(返回用户填写表单,然后在验证后将INSERTS插入数据库)

但我遇到了'编辑用户'的问题。

我的编辑表单是SAME作为添加表单,但文本框的值用数据库中的值填充。

提交后,逻辑检查用户输入和数据库值之间的不匹配(所以我们知道我们在数据库中实际更新了什么)

所以我最终得到了一个需要更改的所有值的数组,例如:

$values_to_update = array (
    "telephone" => "07788991010"
    "email_address" => "my_new_email_address@host.com"
);

这个数组中的值是动态的,我需要一种动态更新每个字段的方法。

此外,这些字段也可能来自不同的表格。

我不想这样做:

if ( isset ( $values_to_update[ "telephone" ] ) )
    $database->update("UPDATE users SET telephone = '{$values_to_update[ "telephone" ]}' WHERE user_id = $user_id");

else if ( isset ( $values_to_update[ "email_address" ] ) )
    $database->update("UPDATE authentication SET email_address = '{$values_to_update[ "email_address" ]}' WHERE user_id = $user_id");

else if ( /* ... */)
    // etc etc etc

有没有人有更好的方法可以做到这一点?

我想也许我可以使用一个巨大的更新语句使用相同的选择状态来获取数据。但我不知道这会如何运作。

应用程序将一组字段存储到表中以进行动态查询生成是一种标准做法吗?

1 个答案:

答案 0 :(得分:4)

我发现在PDO风格的ORM映射器(也在Zend Framework中使用)中执行此操作的一种干净方式:

public function save($model) {
    // Possible values to insert
    $values = array(
        ":id" => $model->id,
        ":name" => $model->name,
        //...
        ":contact_number" => $model->telephone
    );

    // If model id is set, we are updating a record, otherwise inserting
    if (isset($model->id)) {
        $sql = "UPDATE tbl SET name = :name, ..., contact_number = :contact_number WHERE id = :id LIMIT 1";
    } else {
        // Don't pass the ID when it isn't in the query
        unset($values[":id"]);
        $sql = "INSERT INTO tbl (name, ..., contact_number) VALUES (:name, ..., :contact_number)";
    }

    // Execute the query with our values (below is a PDO example)
    $stmt = $this->db->prepare($sql);
    $stmt->execute($values);
    $stmt->closeCursor();

    // Get the new ID if we inserted
    if (!isset($model->id)) {
        $model->id = $this->db->lastInsertId();
    }

    return $model;
}

通常这相当于为每个模型编写一个save方法。您可以在UPDATE情况下通过保留最初检索的模型的副本来扩展它,以便您只更新已更改的列,但是通过更新所有列我没有看到任何巨大的开销。