PHP ORM框架與簡單代碼實現

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

一、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框架。mysql

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

二、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/架構

三、EZPDO

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

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

四、RedBean

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

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

五、其餘

國內的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);
 
?>
相關文章
相關標籤/搜索