PHP ORM框架與簡單代碼實現

讓OOP與關系數據庫更融洽
服務器君一共花費了66.044 ms進行了4次數據庫查詢,努力地為您提供了這個頁面。
試試閱讀模式?希望聽取您的建議

對象關系映射(Object Relational Mapping,簡稱ORM)是一種為了解決面向對象與關系數據庫存在的互不匹配的現象的技術。 簡單的說,ORM是通過使用描述對象和數據庫之間映射的元數據,將程序中的對象自動持久化到關系數據庫中。本質上就是將數據從一種形式轉換到另外一種形式。

ORM提供了所有SQL語句的生成,代碼人員遠離了數據庫概念。從一個概念需求(例如一個HQL)映射為一個SQL語句,并不需要什么代價,連1%的性能損失都沒有。真正的性能損失在映射過程中,更具體地講,是在對象實例化的過程中。

目前PHP 開源比較有名的 ORM 有以下幾個:

1、Propel

Propel是一個適用于PHP5的ORM映射(Object Relational Mapping)框架,它基于Apache Torque提供對象持久層支持。它通過XML格式的模式定義文件和相應的配置文件來生成SQL和類,它允許你使用對象代替SQL來讀寫數據庫表中的記錄。Propel提供一個生成器來為你的數據模型創建SQL定義文件和PHP類。開發者也可以十分簡單的定制生成的類,我們還可以通過XML, PHP類和Phing構建工具把Propel集成到已有的應用開發框架中去.例如PHP框架symfony的1.2以前的版本就是默認使用了精簡版的Propel作為默認ORM框架。

官方網站:http://www.propelorm.org/

2、Doctrine

Doctrine是一個PHP的ORM框架,它必須運行在>=php5.2.3版本上,它是一個功能強大的數據抽象層。

它的一個主要特征就是使用面向對象的方式來實現數據庫查詢的封轉,它底層通過一個類似 Hibernate HQL的DQL的查詢語句進行數據庫查詢,這使得開發的靈活性更強,大大減小了重復代碼。相比Propel,Doctrine的優點在于它支持支持全文檢索,Doctrine的文檔一直就比Propel要全面豐富,社區更活躍,而且使用起來更加自然、更易閱讀、更接近原生SQL。性能方面也略微優于Propel。同樣你也可以可以很方便的把Doctrine集成到現有的應用框架中去,比如PHP框架symfony的1.3以后的版本將Doctrine作為默認的ORM框架,同時也可以將Doctrine和Codeigniter整合起來。

官方網站: http://www.doctrine-project.org/

3、EZPDO

EZPDO是一個十分輕量級的PHP ORM框架。EZPDO的作者的本意旨在降低復雜的ORM學習曲線,盡可能在ORM的運行效率和功能之間做一個平衡點,它是我至今用過的最簡單的ORM框架,我目前還想將它集成到我的CoolPHP SDK中來,而且運行效率相當不錯,功能也基本能滿足需求,只不過ESPDO的更新比較緩慢。

官方網站:http://www.ezpdo.net/blog/?p=2

4、RedBean

RedBean是一個易于使用,輕量級PHP ORM框架,提供對MySQL, SQLite&PostgreSQL的支持。RedBean架構非常靈活,核心也非常簡約,開發者可以很方便的通過插件來擴展功能。

官方網站:http://www.redbeanphp.com/

5、其他

國內的fleaphp開發框架基于TableDataGateway實現ORM實現;Zend Framework除了提供對 SQL 語句的封裝以外,也同樣實現了TableGateway、TableRowSet、TableRow的實現;還有一些類似Rails的ActiveRecord實現的解決方案。

總的來說,一般ORM框架對付簡單的應用系統來說都能滿足基本需求,可以大大降低開發難度,提高開發效率,但是它在SQL優化方面,肯定是比純SQL語言要差一些,對復雜關聯、SQL內嵌表達式的處理可能不是很理想。也許這主要是由于PHP本身對象持久化的問題,導致ORM效率過低,普遍比純SQL要慢。但是這些都是有辦法解決的,最基本的解決性能的方案,我們可以通過緩存來提高效率,Hibernate來說,雖然配置比較繁雜,但是它通過靈活的使用二級緩存和查詢緩存極大的緩解數據庫的查詢壓力,極大的提升了系統的性能。

如果你想自己實現一個PHP的ORM,下面的可以參考下:

<?php
abstract class Model{
   protected $pk = 'id';
   protected $_ID = null; 
   protected $_tableName;
   protected $_arRelationMap;
   protected $_modifyMap;
   protected $is_load = false;
   protected $_blForDeletion;
   protected $_DB;

   public function __consturct($id = null){
       $this->_DB = mysql_connect('127.0.0.1','root','') ;
       $this->_tableName = $this->getTableName();
       $this->_arRelationMap = $this->getRelationMap();
       if(isset($id))$this->_ID = $id;
   }
   abstract protected function getTableName();
   abstract protected function getRelationMap();

   public function Load(){
       if(isset($this->_ID)){
           $sql = "SELECT ";
           foreach($this->_arRelationMap as $k => $v){
               $sql .= '`'.$k.'`,';
           }
           $sql .= substr($sql,0,strlen($sql)-1);
           $sql .= "FROM ".$this->_tableName." WHERE ".$this->pk." = ".$this->_ID;
           $result =$this->_DB->mysql_query($sql);
           foreach($result[0] as $k1 => $v1){
              $member = $this->_arRelationMap[$key];
              if(property_exists($this,$member)){
                 if(is_numeric($member)){
                     eval('$this->'.$member.' = '.$value.';');
                 }else{
                     eval('$this->'.$member.' = "'.$value.'";');
                 }
              }
           }
       }
       $this->is_load = true;
   }
   public function __call($method,$param){
      $type   = substr($method,0,3);
      $member = substr($method,3);
      switch($type){
         case 'get':
             return $this->getMember($member);
             break;
         case 'set':
             return $this->setMember($member,$param[0]);
      }
      return false;
   }
   public function setMember($key){
       if(property_exists($this,$key)){
          if(is_numeric($val)){
             eval('$this->'.$key.' = '.$val.';');
          }else{
             eval('$this->'.$key.' = "'.$val.'";');
          }
          $this->_modifyMap[$key] = 1;
       }else{
          return false;
       }
   }
   
   public function getMember($key,$val){
       if(!$this->is_load){
          $this->Load();
       }
       if(property_exists($this,$key)){
          eval('$res = $this->'.$key.';' );
          return $this->$key;
       }
       return false;
   }

   public function save(){
      if(isset($this->_ID)){
          $sql = "UPDATE ".$this->_tableName." SET ";
          foreach($this->arRelationMap as $k2 => $v2){
              if(array_key_exists( $k2, $this->_modifyMap)){
                  eval( '$val = $this->'.$v2.';');
                  $sql_update .=  $v2." = ".$val;
              }
          }
          $sql .= substr($sql_update,0,strlen($sql_update));
          $sql .= 'WHERE '.$this->pk.' = '.$this->_ID;
      }else{
          $sql = "INSERT INTO ".$this->_tableName." (";
          foreach($this->arRelationMap as $k3 => $v3){
              if(array_key_exists( $k3,$this->_modifyMap)){
                  eval('$val = $this->'.$v3.';');
                  $field  .= "`".$v3."`,"; 
                  $values .= $val;
              }
          }
          $fields = substr($field,0,strlen($field)-1);
          $vals   = substr($values,0,strlen($values)-1);
          $sql .= $fields." ) VALUES (".$vals.")";
      }
      echo $sql;
      //$this->_DB->query($sql);
   }
   public function __destory(){
      if(isset($this->ID)){
         $sql = "DELETE FROM ".$this->_tableName." WHERE ".$this->pk." = ".$this->_ID;
        // $this->_DB_query($sql);
      }
   }
}

class User extends Model{
    protected  function getTableName(){
       return "test_user";
    }
    protected function getRelationMap(){
        return array( 
                      'id'       => USER_ID,
                      'user_name'=> USER_NAME,
                      'user_age' => USER_AGE
                    );
    }
    public function getDB(){
       return $this->_DB;
    }
}

$UserIns = new User();
print_r($UserIns);

?>

本文地址:http://www.zqhthc.tw/librarys/veda/detail/2169,歡迎訪問原出處。

不打個分嗎?

轉載隨意,但請帶上本文地址:

http://www.zqhthc.tw/librarys/veda/detail/2169

如果你認為這篇文章值得更多人閱讀,歡迎使用下面的分享功能。
小提示:您可以按快捷鍵 Ctrl + D,或點此 加入收藏

大家都在看

閱讀一百本計算機著作吧,少年

很多人覺得自己技術進步很慢,學習效率低,我覺得一個重要原因是看的書少了。多少是多呢?起碼得看3、4、5、6米吧。給個具體的數量,那就100本書吧。很多人知識結構不好而且不系統,因為在特定領域有一個足夠量的知識量+足夠良好的知識結構,系統化以后就足以應對大量未曾遇到過的問題。

奉勸自學者:構建特定領域的知識結構體系的路徑中再也沒有比學習該專業的專業課程更好的了。如果我的知識結構體系足以囊括面試官的大部分甚至吞并他的知識結構體系的話,讀到他言語中的一個詞我們就已經知道他要表達什么,我們可以讓他坐“上位”畢竟他是面試官,但是在知識結構體系以及心理上我們就居高臨下。

所以,閱讀一百本計算機著作吧,少年!

《人月神話》 弗雷德里克·布魯克斯 (作者), 汪穎 (譯者)

《人月神話》原文:The Mythical Man-Month: The Essays on Software Engineering, 2nd ed.在軟件領域,很少能有像《人月神話》一樣具有深遠影響力并且暢銷不衰的著作。Brooks博士為人們管理復雜項目提供了最具洞察力的見解。既有很多發人深省的觀點,又有大量軟件工程的實踐。本書內容來自Brooks博士在IBM公司System/360家族和OS/360中的項目管理經驗。該書英文原版一經面世,即引起業內人士的強烈反響,后又譯為德、法、日、俄中等多種語言,全球銷量數百萬冊。確立了其在行業內的經典地位。

更多計算機寶庫...

英超直播吻球网