0

图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();

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

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

4

3 回答 3

0

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

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

于 2015-01-26T23:24:24.290 回答
0
  1. 声明一个 PRISTINE 常量。尝试将其设置为您创建的对象的新实例,例如 new MyPristine。
  2. 在您的 Game 构造函数中,将所有字段设置为该常量。这是将它们标记为“未触及”的技巧。您可以使用反射(如 ReflectionClass($game)->getProperties() )循环所有这些
  3. 在保存之前,再次遍历字段并使用 PRISTINE 测试它们的值。如果不同,则需要更改。

这个解决方案假设没有人/没有其他人会在第 2 步和第 3 步之间更改 Game 实例。这就是为什么大多数 ORM 会事先执行 SELECT 的原因。

于 2015-01-27T03:00:28.510 回答
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

于 2015-01-26T23:27:40.703 回答