DatabaseObject Quentin Zervaas#39;s DBO
Quentin Zervaas#39;s DBO 《Web 2.0 开发实战》一书的作者,Quentin Zervaas 在书中提到的一个简易PHP数据访问对象。**DatabaseObject.php**[代码片段(295行)]**DatabaseObject_User**[代码片段(224行)]
《Web 2.0 开发实战》一书的作者,Quentin Zervaas 在书中提到的一个简易PHP数据访问对象。
DatabaseObject.php
<?php /** * DatabaseObject * * Abstract class used to easily manipulate data in a database table * via simple load/save/delete methods */ abstract class DatabaseObject { const TYPE_TIMESTAMP = 1; const TYPE_BOOLEAN = 2; protected static $types = array(self::TYPE_TIMESTAMP, self::TYPE_BOOLEAN); private $_id = null; private $_properties = array(); protected $_db = null; protected $_table = ''; protected $_idField = ''; public function __construct(Zend_Db_Adapter_Abstract $db, $table, $idField) { $this->_db = $db; $this->_table = $table; $this->_idField = $idField; } public function load($id, $field = null) { if (strlen($field) == 0) $field = $this->_idField; if ($field == $this->_idField) { $id = (int) $id; if ($id <= 0) return false; } $query = sprintf('select %s from %s where %s = ?', join(', ', $this->getSelectFields()), $this->_table, $field); $query = $this->_db->quoteInto($query, $id); return $this->_load($query); } protected function getSelectFields($prefix = '') { $fields = array($prefix . $this->_idField); foreach ($this->_properties as $k => $v) $fields[] = $prefix . $k; return $fields; } protected function _load($query) { $result = $this->_db->query($query); $row = $result->fetch(); if (!$row) return false; $this->_init($row); $this->postLoad(); return true; } public function _init($row) { foreach ($this->_properties as $k => $v) { $val = $row[$k]; switch ($v['type']) { case self::TYPE_TIMESTAMP: if (!is_null($val)) $val = strtotime($val); break; case self::TYPE_BOOLEAN: $val = (bool) $val; break; } $this->_properties[$k]['value'] = $val; } $this->_id = (int) $row[$this->_idField]; } public function save($useTransactions = true) { $update = $this->isSaved(); if ($useTransactions) $this->_db->beginTransaction(); if ($update) $commit = $this->preUpdate(); else $commit = $this->preInsert(); if (!$commit) { if ($useTransactions) $this->_db->rollback(); return false; } $row = array(); foreach ($this->_properties as $k => $v) { if ($update && !$v['updated']) continue; switch ($v['type']) { case self::TYPE_TIMESTAMP: if (!is_null($v['value'])) { if ($this->_db instanceof Zend_Db_Adapter_Pdo_Pgsql) $v['value'] = date('Y-m-d H:i:sO', $v['value']); else $v['value'] = date('Y-m-d H:i:s', $v['value']); } break; case self::TYPE_BOOLEAN: $v['value'] = (int) ((bool) $v['value']); break; } $row[$k] = $v['value']; } if (count($row) > 0) { // perform insert/update if ($update) { $this->_db->update($this->_table, $row, sprintf('%s = %d', $this->_idField, $this->getId())); } else { $this->_db->insert($this->_table, $row); $this->_id = $this->_db->lastInsertId($this->_table, $this->_idField); } } // update internal id if ($commit) { if ($update) $commit = $this->postUpdate(); else $commit = $this->postInsert(); } if ($useTransactions) { if ($commit) $this->_db->commit(); else $this->_db->rollback(); } return $commit; } public function delete($useTransactions = true) { if (!$this->isSaved()) return false; if ($useTransactions) $this->_db->beginTransaction(); $commit = $this->preDelete(); if ($commit) { $this->_db->delete($this->_table, sprintf('%s = %d', $this->_idField, $this->getId())); } else { if ($useTransactions) $this->_db->rollback(); return false; } $commit = $this->postDelete(); $this->_id = null; if ($useTransactions) { if ($commit) $this->_db->commit(); else $this->_db->rollback(); } return $commit; } public function isSaved() { return $this->getId() > 0; } public function getId() { return (int) $this->_id; } public function getDb() { return $this->_db; } public function __set($name, $value) { if (array_key_exists($name, $this->_properties)) { $this->_properties[$name]['value'] = $value; $this->_properties[$name]['updated'] = true; return true; } return false; } public function __get($name) { return array_key_exists($name, $this->_properties) ? $this->_properties[$name]['value'] : null; } protected function add($field, $default = null, $type = null) { $this->_properties[$field] = array('value' => $default, 'type' => in_array($type, self::$types) ? $type : null, 'updated' => false); } protected function preInsert() { return true; } protected function postInsert() { return true; } protected function preUpdate() { return true; } protected function postUpdate() { return true; } protected function preDelete() { return true; } protected function postDelete() { return true; } protected function postLoad() { return true; } public static function BuildMultiple($db, $class, $data) { $ret = array(); if (!class_exists($class)) throw new Exception('Undefined class specified: ' . $class); $testObj = new $class($db); if (!$testObj instanceof DatabaseObject) throw new Exception('Class does not extend from DatabaseObject'); foreach ($data as $row) { $obj = new $class($db); $obj->_init($row); $ret[$obj->getId()] = $obj; } return $ret; } }
精彩图集
精彩文章