목차
1、Propel
2、Doctrine
3、EZPDO
4、RedBean
5、其他
백엔드 개발 PHP 튜토리얼 PHP ORM框架与容易代码实现

PHP ORM框架与容易代码实现

Jun 13, 2016 pm 12:54 PM
function gt protected sql this

PHP ORM框架与简单代码实现

对象关系映射(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);

?>
로그인 후 복사

?

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Hibernate 프레임워크에서 HQL과 SQL의 차이점은 무엇입니까? Hibernate 프레임워크에서 HQL과 SQL의 차이점은 무엇입니까? Apr 17, 2024 pm 02:57 PM

HQL과 SQL은 Hibernate 프레임워크에서 비교됩니다. HQL(1. 객체 지향 구문, 2. 데이터베이스 독립적 쿼리, 3. 유형 안전성), SQL은 데이터베이스를 직접 운영합니다(1. 데이터베이스 독립적 표준, 2. 복잡한 실행 파일) 쿼리 및 데이터 조작).

화웨이 GT3 Pro와 GT4의 차이점은 무엇입니까? 화웨이 GT3 Pro와 GT4의 차이점은 무엇입니까? Dec 29, 2023 pm 02:27 PM

많은 사용자들이 스마트 시계를 선택할 때 Huawei 브랜드를 선택하게 됩니다. 그 중 Huawei GT3pro와 GT4가 가장 인기 있는 선택입니다. 두 제품의 차이점을 궁금해하는 사용자가 많습니다. Huawei GT3pro와 GT4의 차이점은 무엇입니까? 1. 외관 GT4: 46mm와 41mm, 재질은 유리 거울 + 스테인레스 스틸 본체 + 고해상도 섬유 후면 쉘입니다. GT3pro: 46.6mm 및 42.9mm, 재질은 사파이어 유리 + 티타늄 본체/세라믹 본체 + 세라믹 백 쉘입니다. 2. 건강한 GT4: 최신 Huawei Truseen5.5+ 알고리즘을 사용하면 결과가 더 정확해집니다. GT3pro: ECG 심전도, 혈관 및 안전성 추가

Oracle SQL의 나누기 연산 사용법 Oracle SQL의 나누기 연산 사용법 Mar 10, 2024 pm 03:06 PM

"OracleSQL의 나눗셈 연산 사용법" OracleSQL에서 나눗셈 연산은 일반적인 수학 연산 중 하나입니다. 데이터 쿼리 및 처리 중에 나누기 작업은 필드 간의 비율을 계산하거나 특정 값 간의 논리적 관계를 도출하는 데 도움이 될 수 있습니다. 이 문서에서는 OracleSQL의 나누기 작업 사용법을 소개하고 구체적인 코드 예제를 제공합니다. 1. OracleSQL의 두 가지 분할 연산 방식 OracleSQL에서는 두 가지 방식으로 분할 연산을 수행할 수 있습니다.

Oracle과 DB2의 SQL 구문 비교 및 ​​차이점 Oracle과 DB2의 SQL 구문 비교 및 ​​차이점 Mar 11, 2024 pm 12:09 PM

Oracle과 DB2는 일반적으로 사용되는 관계형 데이터베이스 관리 시스템으로, 각각 고유한 SQL 구문과 특성을 가지고 있습니다. 이 기사에서는 Oracle과 DB2의 SQL 구문을 비교 및 ​​차이점을 설명하고 구체적인 코드 예제를 제공합니다. 데이터베이스 연결 Oracle에서는 다음 문을 사용하여 데이터베이스에 연결합니다. CONNECTusername/password@database DB2에서 데이터베이스에 연결하는 문은 다음과 같습니다. CONNECTTOdataba

MyBatis 동적 SQL 태그의 Set 태그 기능에 대한 자세한 설명 MyBatis 동적 SQL 태그의 Set 태그 기능에 대한 자세한 설명 Feb 26, 2024 pm 07:48 PM

MyBatis 동적 SQL 태그 해석: Set 태그 사용법에 대한 자세한 설명 MyBatis는 풍부한 동적 SQL 태그를 제공하고 데이터베이스 작업 명령문을 유연하게 구성할 수 있는 탁월한 지속성 계층 프레임워크입니다. 그 중 Set 태그는 업데이트 작업에서 매우 일반적으로 사용되는 UPDATE 문에서 SET 절을 생성하는 데 사용됩니다. 이 기사에서는 MyBatis에서 Set 태그의 사용법을 자세히 설명하고 특정 코드 예제를 통해 해당 기능을 보여줍니다. Set 태그란 무엇입니까? Set 태그는 MyBati에서 사용됩니다.

SQL의 ID 속성은 무엇을 의미합니까? SQL의 ID 속성은 무엇을 의미합니까? Feb 19, 2024 am 11:24 AM

SQL에서 ID란 무엇입니까? SQL에서 ID는 자동 증가 숫자를 생성하는 데 사용되는 특수 데이터 유형으로, 테이블의 각 데이터 행을 고유하게 식별하는 데 사용됩니다. ID 열은 일반적으로 기본 키 열과 함께 사용되어 각 레코드에 고유한 식별자가 있는지 확인합니다. 이 문서에서는 Identity를 사용하는 방법과 몇 가지 실제 코드 예제를 자세히 설명합니다. Identity를 사용하는 기본 방법은 테이블을 생성할 때 Identit을 사용하는 것입니다.

SQL에서 5120 오류를 해결하는 방법 SQL에서 5120 오류를 해결하는 방법 Mar 06, 2024 pm 04:33 PM

해결 방법: 1. 로그인한 사용자에게 데이터베이스에 액세스하거나 운영할 수 있는 충분한 권한이 있는지 확인하고 해당 사용자에게 올바른 권한이 있는지 확인하십시오. 2. SQL Server 서비스 계정에 지정된 파일에 액세스할 수 있는 권한이 있는지 확인하십시오. 3. 지정된 데이터베이스 파일이 다른 프로세스에 의해 열렸거나 잠겼는지 확인하고 파일을 닫거나 해제한 후 쿼리를 다시 실행하십시오. .관리자로 Management Studio를 실행해 보세요.

MySQL에서 데이터 집계 및 통계를 위해 SQL 문을 사용하는 방법은 무엇입니까? MySQL에서 데이터 집계 및 통계를 위해 SQL 문을 사용하는 방법은 무엇입니까? Dec 17, 2023 am 08:41 AM

MySQL에서 데이터 집계 및 통계를 위해 SQL 문을 사용하는 방법은 무엇입니까? 데이터 집계 및 통계는 데이터 분석 및 통계를 수행할 때 매우 중요한 단계입니다. 강력한 관계형 데이터베이스 관리 시스템인 MySQL은 데이터 집계 및 통계 작업을 쉽게 수행할 수 있는 풍부한 집계 및 통계 기능을 제공합니다. 이 기사에서는 SQL 문을 사용하여 MySQL에서 데이터 집계 및 통계를 수행하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. COUNT 함수를 사용합니다. COUNT 함수는 가장 일반적으로 사용됩니다.

See all articles