property Gets a property value of the retrieved row (also allows setting) * ->_reload() Reloads the row from the DB * ->_reset() Cancels all the pending changes * ->_update() Commits all the pending changes * ->_refresh() Commits all the pending changes and force reloads the row from the DB * ->_commit() Commits all the pending changes to the object, but not the DB -- read description! * Note: _update() is performed automatically at destruction of the object. (unset() or end of code) * * This code was written and distributed by Teun van Gils as an example of Object Oriented PHP for * a Web Programming course (CSE 154) at the University of Washington, May 2013. * Feel free to alter and use this code as you wish, but please keep a reference to my name in the file. * If you do anything cool with it, or if you have any questions, I'd love to hear from you! * * Contact: * teunvg@cs.washington.edu (Expires July 2013) * t.vangils@students.uu.nl (Expires July 2014) * teunvg@gmail.com */ class liveObject { private $pdo; private $table; private $clause; private $result; private $delta; /* * Constructs a new instance of the liveObject. * * $pdo The PDO object to use for the DB connection. * $table The table to get the row from. * $where The where query to select the row. Results automatically limited to 1. * ORDER BY clause allowed, nothing else. Do not include WHERE keyword. * * Example: * $user = new liveObject($pdo, "users", "username = 'teunvg'"); */ public function __construct($pdo, $table, $where) { $this->pdo = $pdo; $this->table = $table; $this->clause = "$where limit 1"; $this->_reload(); } /* * Gets a property from the resultset of the query. * * Example: * $user->username */ public function __get($name) { return isset($this->delta[$name]) ? $this->delta[$name] : $this->result[$name]; } /* * Sets a property and marks it to be updated in the DB. * * Example: * $user->age = 21 */ public function __set($name, $value) { if (isset($this->result[$name])) { $this->delta[$name] = $value; } } /* * Reloads the resultset without comitting the pending changes to the DB. * * Example: * $user->_reload(); */ public function _reload() { $this->_reset(); $query = "SELECT * FROM {$this->table} WHERE {$this->clause};"; $this->result = $this->pdo->query($query)->fetch(); } /* * Updates the pending changed values in the DB, and commits the changes * to the object, if successful. * * Example: * $user->_update(); */ public function _update() { if (count($this->delta) > 0) { $values = array(); foreach ($this->delta as $column => $value) { $values[] = "$column = " . $this->pdo->quote($value); } $set = implode(", ", $values); $query = "UPDATE {$this->table} SET $set WHERE {$this->clause};"; $result = $this->pdo->query($query); if ($result->rowCount() == 1) { $this->_commit(); } } } /* * Cancels all the pending changes and resets the object to its initial state. * * Example: * $user->_reset(); */ public function _reset() { $this->delta = array(); } /* * Updates the pending changed values in the DB and reloads the resultset to * ensure that all values are up to date. * * Example: * $user->_refresh(); */ public function _refresh() { $this->_update(); $this->_reload(); } /* * Commits the pending changes to the current object, but NOT to the DB. * This causes subsequent DB updates to also not include these changes, * since they are no longer marked as changes internally. * Seldomly needed. * * Example: * $user->_commit(); */ public function _commit() { foreach ($this->delta as $column => $value) { $this->$column = $value; // $this->$column becomes something like $this->username } $this->_reset(); } /* * Returns a string representation of the object. * * Example: * echo $user; */ public function __toString() { return "[liveObject on {$this->table} where {$this->clause}]"; } /* * Updates the pending changed values in the DB when the object is destroyed. (unset() or end of code) * * Example: * unset($user); */ public function __destruct() { $this->_update(); } } ?>