设为首页 收藏本站
查看: 465|回复: 0

[经验分享] PHP ORM框架与简单代码实现——让OOP与关系数据库更融洽

[复制链接]

尚未签到

发表于 2017-4-13 09:36:58 | 显示全部楼层 |阅读模式

对象关系映射(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.nowamagic.net/librarys/veda/detail/2169

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-364247-1-1.html 上篇帖子: php学习笔记(三十九)smarty缓存特性的使用(包括局部缓存) 下篇帖子: 即将重回php怀抱 发文纪念一下 :)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表