如何确定UPDATE动态查询中应包含哪些属性?

时间:2015-01-26 23:07:32

标签: php mysql oop dynamic-queries

图1:这是示例类

的示例
class Games {
    public $id = 0;
    public $date = null;
    public $player1_id = 0;
    public $player2_id = 0;
    public $score = null;

    public function save(){
        if(empty($this->id)){
            // do INSERT here
        }
        else{
            // do UPDATE here  
        }
    }
}

图2:这是一个使用类

的示例
// Save a new date to an existing game
$game = new Games;
$game->id = $input['id'];
$game->date = $input['date'];
$game->save();

如果基于 figure2 执行UPDATE查询,则player1_idplayer2_idscore的值将被错误地覆盖为零/空。因此,我需要一种方法从类内部确定某些属性未设置来自 figure2 中的调用,因此我可以动态地更改UPDATE查询仅更新数据库中的特定字段。还是我接近这个错误?

注意:我知道我可以使用单个array属性来保存所有字段(并使用isset),但这感觉它突破了模型的重点并且会也是非常特定的PHP(因为解决方案不能很好地传输到其他语言,例如JAVA,其中数组是严格键入的?)。我也意识到我可以做我认为ORM所做的事情并在执行更新之前进行初始SELECT查询(但这似乎非常低效!)

3 个答案:

答案 0 :(得分:0)

在更新之前选择您的对象。这样,您的UPDATE语句将包含所有字段。

此外,这可以让您检查ID是否存在。

答案 1 :(得分:0)

否则,在纯SQL中你可以这样做:

UPDATE games SET date = "2015-01-26", anotherField = $game->anotherField() WHERE id = $game->id;

注意:这是伪代码。使用准备好的陈述:http://php.net/manual/en/pdo.prepared-statements.php

反思文档:http://php.net/manual/en/book.reflection.php

答案 2 :(得分:0)

  1. 声明一个PRISTINE常量。尝试将其设置为您创建的对象的新实例,比如新的MyPristine。
  2. 在您的游戏构造函数中,将所有字段设置为该常量。这是将它们标记为“未触及”的技巧。您可以使用Reflection(如ReflectionClass($ game) - > getProperties())循环遍历所有这些
  3. 保存之前,再次遍历字段并使用PRISTINE测试其值。如果不同,则需要更改。
  4. 这个解决方案假设在步骤2和3之间没有人/没有其他任何东西会改变游戏实例。这就是大多数ORM事先会做SELECT的原因。