Object Relational Mapping (ORM) is a technology designed to solve the mismatch between object-oriented and relational databases. Simply put, ORM automatically persists objects in a program into a relational database by using metadata that describes the mapping between objects and databases. Essentially converting data from one form to another.
ORM provides the generation of all SQL statements, and coders are away from database concepts. Mapping from a conceptual requirement (such as a HQL) to a SQL statement costs nothing, not even 1% performance loss. The real performance hit is during the mapping process, and more specifically, during object instantiation.
At present, the more famous PHP open source ORMs include the following:
1. Propel
Propel is an ORM mapping (Object Relational Mapping) framework suitable for PHP5. It provides object persistence layer support based on Apache Torque. It generates SQL and classes through schema definition files in XML format and corresponding configuration files. It allows you to use objects instead of SQL to read and write records in database tables. Propel provides a generator to create SQL definition files and PHP classes for your data model. Developers can also easily customize the generated classes. We can also integrate Propel into existing application development frameworks through XML, PHP classes and Phing build tools. For example, versions before 1.2 of the PHP framework symfony are used by default. A streamlined version of Propel serves as the default ORM framework.
Official website: http://www.propelorm.org/
2. Doctrine
Doctrine is a PHP ORM framework, it must run on >=php5.2.3 version, it is a powerful data abstraction layer.
One of its main features is that it uses an object-oriented approach to implement database query closure. Its bottom layer uses a DQL query statement similar to Hibernate HQL to perform database queries, which makes development more flexible and greatly reduces the time required. Duplicate code. Compared with Propel, the advantage of Doctrine is that it supports full-text search. Doctrine's documentation has always been more comprehensive and richer than Propel, the community is more active, and it is more natural, easier to read, and closer to native SQL. Performance is also slightly better than Propel. Similarly, you can easily integrate Doctrine into existing application frameworks. For example, the 1.3 and later versions of the PHP framework symfony use Doctrine as the default ORM framework, and you can also integrate Doctrine with Codeigniter.
Official website: http://www.doctrine-project.org/
3. EZPDO
EZPDO is a very lightweight PHP ORM framework. The original intention of the author of EZPDO is to reduce the complex ORM learning curve and strike a balance between ORM operating efficiency and functionality as much as possible. It is the simplest ORM framework I have ever used so far, and I still want to integrate it. Come to my CoolPHP SDK, and the running efficiency is quite good, and the functions can basically meet the needs, but the update of EZPDO is relatively slow.
Official website: http://www.ezpdo.net/
4. RedBean
RedBean is an easy-to-use, lightweight PHP ORM framework that provides support for MySQL, SQLite & PostgreSQL. The RedBean architecture is very flexible and the core is very simple. Developers can easily extend functions through plug-ins.
Official website: http://www.redbeanphp.com/
5. Others
The domestic fleaphp development framework implements ORM implementation based on TableDataGateway; Zend Framework, in addition to providing encapsulation of SQL statements, also implements TableGateway, Implementation of TableRowSet and TableRow; there are also some solutions similar to Rails' ActiveRecord implementation.
In general, the general ORM framework can meet the basic needs of simple application systems, which can greatly reduce the difficulty of development and improve development efficiency. However, it is definitely worse than the pure SQL language in terms of SQL optimization. The processing of complex relationships and SQL embedded expressions may not be ideal. Perhaps this is mainly due to the problem of object persistence in PHP itself, which results in ORM being too inefficient and generally slower than pure SQL. But there are ways to solve these. The most basic solution to solve performance, we can improve efficiency through caching. For Hibernate, although the configuration is complicated, it greatly alleviates the problem through the flexible use of second-level cache and query cache. The query pressure of the database greatly improves the performance of the system.
If you want to implement a PHP ORM yourself, you can refer to the following:
<?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); ?>