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

Figure1: Here's an example Model class

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  
        }
    }
}

Figure2: Here's an example use of the class

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

If an UPDATE query is performed based on figure2, then the values for player1_id, player2_id, and score will be incorrectly overwritten to zeros/nulls. Therefore, I need a way to determine from inside the class that certain properties were not set from the call in figure2, so I can dynamically alter the UPDATE query to only update specific fields in the database. Or am I approaching this wrong?

Note: I know I could use a single array property to hold all the fields (and use isset), but this feels like it's breaking the point of the Model and would also be very PHP specific (in that the solution doesn't transfer nicely to other languages such as JAVA where arrays are strictly typed?). I also realize I could do what I think ORMs do and make an initial SELECT query before I perform an update (but that seems very inefficient!)

  1. declare a PRISTINE constant. Try setting it to new instance of an object you've made, say new MyPristine.
  2. In your Game constructor, set all fields to that constant. This is the trick to mark them as " untouched ". You can use Reflection ( like ReflectionClass($game)->getProperties() ) to loop through all of them
  3. Before saving, loop again through the fields and test their value with PRISTINE. If it's different, it needs to be changed.

This solution suppose no one/nothing else will change the Game instances between the steps 2 and 3. That's why most ORMs will do a SELECT beforehand.

Select your object before updating it. That way, your UPDATE statement will contain all the fields.

Also, this let you check that the id exists.

Otherwise, in plain SQL you can do:

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

Note: this is pseudo code. Use prepared statements: http://php.net/manual/en/pdo.prepared-statements.php

Reflection doc: http://php.net/manual/en/book.reflection.php