萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> PHP設計模式之:數據映射模式教程

PHP設計模式之:數據映射模式教程

php中的設計模式中有很多的各種模式了,在這裡我們來為各位介紹一個不常用的數據映射模式吧,希望文章能夠幫助到各位。


之前的幾種設計模式,都是大大提高了PHP代碼的可讀性、可維護性。但是,在WEB應用中還有更重要的需求與挑戰,那就是:數據庫應用。可之前的設計模式,都沒有涉及於此。今天寫到的,數據映射模式就是能夠更好的組織應用程序與數據庫進行交互。
博主這兩天也是花了點時間對,這種模式有了那麼一點的了解。斗膽在這個裡獻丑,按照自己的理解,寫一點東西與大家分享,互相學習。
當然說到數據映射模式,就不得不提到對象關系映射(Object Relational Mapping,簡稱ORM),用於實現面向對象編程語言裡不同類型系統的數據之間的轉換。一般ORM框架對付簡單的應用系統來說都能滿足基本需求,可以大大降低開發難度,提高開發效率,但是它在SQL優化方面,肯定是比純SQL語言要差很多,對復雜關聯、SQL內嵌表達式的處理都不是很理想。
對於博主目前使用的TP框架,其核心文件Model.class.php就是實現了ORM和ActiveRecords模式,在項目中所有的模型也都是繼承這個模型類。
好吧,還是不丟人說這些廢話了,自己參考編寫整理了一份實例,給大家分享一下,互相交流。

首先我們需要一個數據庫中間層實現類,使用pdo進行數據庫訪問。當然這個類不是今天的重點,我也是從網上拷來的,可以直接忽略。

創建一個DB類文件 Db.class.php

<?php
/*
 * 數據庫中間層實現類
 */
class Db { 
    public static $db = null; 
    private $_dbh = null; 
    public static function getInstance() { 
        if( self::$db == null ){ 
            self::$db = new self(BACKEND_DBHOST ,BACKEND_DBUSER ,BACKEND_DBPW ,BACKEND_DBNAME); 
        } 
        return self::$db; 
    }
 
    private function __construct( $host ,$user ,$pass ,$dbname ){ 
        try { 
            $this->_dbh = new PDO('mysql:dbname='.$dbname.';host='.$host,$user,$pass); 
            $this->_dbh->query('SET NAMES '. BACKEND_DBCHARSET); 
            $this->_dbh->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); 
            $this->_dbh->setAttribute(PDO::ATTR_ERRMODE, true); 
        } catch (PDOException $e) { 
            throw new Exception('Can not connect db'); 
        } 
    }
    public function getOne($sql){ 
        try { 
            $rs = $this->_dbh->query($sql); 
            $result = $rs->fetch(PDO::FETCH_ASSOC); 
            if(!empty($result)) { 
                return $result; 
            } 
        } catch (PDOException $e) { 
            throw new Exception($this->_dbh->errorInfo()); 
        } 
        return false; 
    } 
 
    public function getAll($sql){ 
        try { 
            $rs = $this->_dbh->query($sql); 
            $result = $rs->fetchAll(PDO::FETCH_ASSOC); 
            if(!empty($result)) { 
                return $result; 
            } 
        } catch (PDOException $e) { 
            throw new Exception($this->_dbh->errorInfo()); 
        } 
        return false; 
    } 
 
    public function exec($sql){ 
        try { 
            $exec = $this->_dbh->exec($sql); 
        } catch (PDOException $e){ 
            throw new Exception($this->_dbh->errorInfo()); 
        } 
        return $exec;
    }
 
    public function getLastId() 
    { 
        return $this->_dbh->lastInsertId(); 
    } 
} 
?>

數據映射類 Table.class.php

<?php
/** 
 * 數據映射類
 * 部分代碼來源TP框架
 * 使用相關魔術方法 則映射的表修改字段後無需修改屬性值
 */ 
class Table{
 
    // 數據信息
    protected $data = array();
 
    // 數據信息
    protected $db = null;
 
    // 表信息
    protected $tableName = '';
    public function __construct() {
        $this->db = Db::getInstance();
    }
 
    /**
     * 設置數據對象的值
     */
    public function __set($name,$value) {
        // 設置數據對象屬性
        $this->data[$name] = $value;
    }
    /**
     * 獲取數據對象的值
     */
    public function __get($name) {
        return isset($this->data[$name])?$this->data[$name]:null;
    }
 
    /*
     * 添加
     * 修改、刪除也和添加類似,就不一一列舉了
     */
    public function add() {
        $data = $this->data;
        foreach($data as $k=>$v) {
            $fieldArr[] = $k;
            $valueArr[] = "'".$v."'";
        }
        $fields = implode(',', $fieldArr);
        $values = implode(',', $valueArr);
        $sql = 'INSERT INTO '.$this->tableName.' ('.$fields.') VALUES ('.$values.')';
        $result = $this->db->exec($sql);
        if($result) {
            return $this->db->getLastId();
        } else {
            return false;
        }
    }
}
?>

表對應的類文件 UserTable.class.php

<?php
/** 
 * 數據映射到表 
 * 一般根據表的結構由工具自動生成,比如Yii框架等。
 */
class UserTable extends Table { 
    protected $tableName = 'user';
}
?>
 
使用方式 index.php
<?php
/** 
 * 數據庫配置文件 
 */ 
define('BACKEND_DBHOST', 'localhost'); 
define('BACKEND_DBUSER', 'root'); 
define('BACKEND_DBPW', ''); 
define('BACKEND_DBNAME', 'test'); 
define('BACKEND_DBCHARSET', 'utf-8');
/*
 * 這裡實例化對象時可以使用之前介紹的工廠模式和注冊模式,來實例化和管理實例化對象
 * TP框架中的D方法就是做了這部分工作
 */
$UserTable = new UserTable();
$UserTable->username = 'Anrai';
$UserTable->mobile = '123456789';
$UserTable->email = '[email protected]';
echo $UserTable->add();
/*
數據表sql
CREATE TABLE `user` (
 `uid` int(11) NOT NULL AUTO_INCREMENT,
 `username` varchar(30) NOT NULL,
 `mobile` varchar(11) NOT NULL DEFAULT '0',
 `email` varchar(60) NOT NULL DEFAULT '0',
 PRIMARY KEY (`uid`),
 KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
*/
?>

copyright © 萬盛學電腦網 all rights reserved