龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > php编程 >

DatabaseObject Quentin Zervaas#39;s DBO

时间:2015-06-04 02:29来源:网络整理 作者:网络 点击:
分享到:
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;
        }
    }

精彩图集

赞助商链接