基于PHP简单的ORM实现(postgresql)http://xialluyouyue.iteye.com/blog/2237114
为了减少不必要的数据库查询,对数据库的影响,代码复制,我们需要更加智能方式实现ORM,需要惰性实例化,属性监控,代码可重用性,减少对底层数据库影响以及不必要主动查询的危险。
定义一个DataboundObject类,该类是一个抽象类,不仅提供子类不需要重新生成最终方法(并且,通过final关键字表明该方法不可以重载),还声明了某些必须子类实现的方法,该类可以直接放在工具类中。
命名:DataBoundObject.php
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
abstract class DataBoundObject {
protected $ID;
protected $objPDO;
protected $strTableName;
protected $arRelationMap;
protected $blForDeletion;
protected $blIsLoaded;
protected $arModifiedRelation;
abstract protected function DefineTableName();
abstract protected function DefineRelationMap();
public function __construct(PDO $objPDO,$id = null) {
$this->strTableName = $this->DefineTableName();
$this->arRelationMap = $this->DefineRelationMap();
$this->objPDO = $objPDO;
$this->blIsLoaded = false;
if(isset($id)){
$this->ID = $id;
}
$this->arModifiedRelation = [];
}
public function load(){
if(isset($this->ID)){
$strQuery = "SELECT ";
foreach ($this->arRelationMap as $key => $value) {
$strQuery .= "\"".$key."\",";
}
$strQuery = substr($strQuery, 0, strlen($strQuery)-1);
$strQuery .=" FROM ".$this->strTableName." WHERE \"id\" = :eid";
$objStatement = $this->objPDO->prepare($strQuery);
$objStatement->bindParam(':eid', $this->ID, PDO::PARAM_INT);
$objStatement->execute();
$arRow = $objStatement->fetch(PDO::FETCH_ASSOC);
foreach ($arRow as $key => $value) {
$strMember = $this->arRelationMap[$key];
if(property_exists($this, $strMember)){
if(is_numeric($value)){
eval('$this->'.$strMember .' = '.$value.';');
}else{
eval('$this->'.$strMember.' = "'.$value.'";');
}
}
}
$this->blIsLoaded = true;
}
}
public function Save(){
if(isset($this->ID)){
$strQuery = 'UPDATE "'.$this->strTableName.'" SET ';
foreach ($this->arRelationMap as $key => $value) {
eval('$actualVal = &$this->'.$value.';');
if(array_key_exists($value, $this->arModifiedRelation)){
$strQuery .= '"' .$key. "\" = :$value,";
}
}
$strQuery = substr($strQuery, 0,strlen($strQuery)-1);
$strQuery .=' WHERE "id"=:eid';
unset($objStatement);
$objStatement = $this->objPDO->prepare($strQuery);
$objStatement->bindValue(':eid', $this->ID, PDO::PARAM_INT);
foreach ($this->arRelationMap as $key => $value) {
eval('$actualVal = &$this->'.$value.';');
if(array_key_exists($value, $this->arModifiedRelation)) {
if(is_int($actualVal)){
$objStatement->bindValue(':'.$value, $this->$value, PDO::PARAM_INT);
}elseif($actualVal == NULL){
//postgresql:if some column type is null,update will cause error,u need insert null,not ''
$objStatement->bindValue(':'.$value, NULL, PDO::PARAM_STR);
}else{
$objStatement->bindValue(':'.$value, $this->$value, PDO::PARAM_STR);
}
}
}
$objStatement->execute();
echo '更新成功';exit;
}else{
$strValueList = "";
$strQuery = 'INSERT INTO "'.$this->strTableName.'" (';
foreach ($this->arRelationMap as $key => $value) {
eval('$actualVal = &$this->'.$value.';');
if(isset($actualVal)){
if(array_key_exists($value, $this->arModifiedRelation)){
$strQuery .= '"' .$key. '",';
$strValueList .= ":$value,";
}
}
}
$strQuery = substr($strQuery, 0, strlen($strQuery)-1);
$strValueList = substr($strValueList, 0, strlen($strValueList)-1);
$strQuery .= ") VALUES (";
$strQuery .= $strValueList;
$strQuery .= ")";
unset($objStatement);
$objStatement = $this->objPDO->prepare($strQuery);
foreach ($this->arRelationMap as $key => $value) {
eval('$actualVal = &$this->'.$value.';');
if(isset($actualVal)){
if(array_key_exists($value, $this->arModifiedRelation)){
if(is_int($actualVal) || $actualVal == NULL){
$objStatement->bindValue(':'.$value, $actualVal, PDO::PARAM_INT);
}else{
$objStatement->bindValue(':'.$value, $actualVal, PDO::PARAM_STR);
}
}
}
}
$objStatement->execute();
$this->ID = $this->objPDO->lastInsertId($this->strTableName."_id_seq");
}
}
public function MarkFordeletion(){
$this->blForDeletion = true;
}
public function __destruct() {
if(isset($this->ID)){
if($this->blForDeletion == true){
$strQuery = 'DELETE FROM "'.$this->strTableName.'" WHERE "id" =:eid';
$objStatement = $this->objPDO->prepare($strQuery);
$objStatement->bindValue(':eid', $this->ID, PDO::PARAM_INT);
$objStatement->execute();
echo '删除成功';exit;
}
}
}
public function __call($strFunction, $arArguments) {
$strMethodType = substr($strFunction, 0,3);
$strMethodMember = substr($strFunction, 3);
switch ($strMethodType) {
case 'set':
return ($this->SetAccessor($strMethodMember, $arArguments[0]));
break;
case 'get':
return ($this->GetAccessor($strMethodMember));
}
return (false);
}
private function SetAccessor($strMember,$strNewValue){
if(property_exists($this, $strMember)){
if(is_numeric($strNewValue)){
eval('$this->'.$strMember.' = '.$strNewValue.';');
}else{
eval('$this->'.$strMember.' = "'.$strNewValue.'";');
}
$this->arModifiedRelation[$strMember] = "1";
}else{
return (false);
}
}
private function GetAccessor($strMember){
if($this->blIsLoaded != true){
$this->load();
}
if(property_exists($this, $strMember)){
eval('$strRetVal = $this->'.$strMember.';');
return ($strRetVal);
}else{
return (false);
}
}
}
我们还是用system_user表(postgresql)
定义User类进行继承DataBoundObject类,
命名User.php
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
require_once 'DataBoundObject.php';
class User extends DataBoundObject{
protected $FirstName;
protected $LastName;
protected $Username;
protected $Password;
protected $EmailAddress;
protected $DateLastLogin;
protected $TimeLastLogin;
protected $DateAccountCreated;
protected $TimeAccountCreated;
protected function DefineTableName() {
return ("system_user");
}
protected function DefineRelationMap() {
return ([
"id" => "ID",
"first_name" => "FirstName",
"last_name" => "LastName",
"username" => "Username",
"md5_pw" => "password",
"email_address" => "EmailAddress",
"date_last_login" => "DateLastLogin",
"time_last_login" => "TimeLastLogin",
"date_account_created" => "DateAccountCreated",
"time_account_created" => "TimeAccountCreated"
]);
}
}
下面我们进行测试:
命名为TestSystemUser.php
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
require_once 'PdoFactory.php';
require_once 'DataBoundObject.php';
require_once 'User.php';
$dsn ="pgsql:host=192.168.1.234;port=5432;dbname=dbname;";
$objPdo = PdoFactory::getPDO($dsn,'postgres','123456',[]);
$objUser = new User($objPdo);
$objUser->setFirstName('Kavin');
$objUser->setLastName('Green');
$objUser->setDateAccountCreated(date('Y-m-d'));
print "First name is ".$objUser->getFirstName()."<br />";
print "Last name is ".$objUser->getLastName()."<br />";
$objUser->Save();
$id = $objUser->getID();
print "ID in database is".$id."<br />";
unset($objUser);
$objUser = new User($objPdo,$id);
$objUser->setFirstName('Tobo11');
$objUser->setLastName('Jimlin111');
print "Saving.....";
$objUser->Save();
测试结果
First name is Kavin
Last name is Green
ID in database is18
Saving.....更新成功
上述基本是ORM实现基本原理,需要进一步进行该进,只是测试用。
相关推荐
codeigniter 3.X的ORM 设计,方便大家使用。您也可以前往composer下载:PHP kichijyo/codeigniter3.x_orm_model,具体使用说明请参考composer的markdown文本。命令:composer require kichijyo/codeigniter3.x_orm_...
总结来说,“php数据库访问封装类集合”是一个包含多种数据库访问实现的资源,可以帮助PHP开发者更方便地进行数据库操作。通过理解并运用这些封装类,我们可以提高代码的效率和安全性,同时降低维护成本。
ORM的核心思想是通过创建一个映射文件或使用注解,将数据库的表与程序中的类关联起来,每个表对应一个类,表中的字段对应类的属性。这样,当我们在程序中操作对象时,实际上是在操作数据库中的数据,反之亦然。ORM...
自主封装的PHP ORM框架,面向对象的PDO数据库操作,API框架,支持Get/Post/Put/Delete多种请求方式。 代码示例: <?php use Models\User; require '../application.php'; require '../loader-api.php'; //适合...
PHP提供了丰富的数组函数,如`array_push`、`array_pop`、`array_map`、`array_filter`等,用于对数组进行各种操作。例如,我们可以使用`array_map`函数将数组中的所有元素转换为大写: ```php $array = ['hello',...
13. **对象-关系映射(ORM)类**:简化数据库操作,如Doctrine、Eloquent等。 14. **模板渲染类**:如Twig、Smarty,用于动态生成HTML页面。 15. **图像处理类**:如GD库或Imagick,支持图片的裁剪、缩放、水印等...
### 货拉拉SDK开放平台php版本SDK封装案例thinkphp和yaf框架解析 #### 一、货拉拉SDK开放平台概述 货拉拉SDK开放平台为开发者提供了丰富的接口和工具,支持多种语言和框架,其中php版本的SDK特别适用于基于PHP语言...
同时,利用`Error`类和`ErrorException`类进行更精细的错误控制。日志记录类则可以帮助开发者将错误信息或调试信息记录到文件,如自定义的日志类,集成`error_log()`函数。 2. **字符串操作**:PHP提供了`String`类...
在PHP中,MySQL封装类是一种常见的做法,它允许开发者将与数据库交互的代码集中在一个类中,从而提高代码的可读性、可维护性和复用性。以下是一个PHP实现的MySQL封装类的详细解析: 首先,我们看到类名为`Mysql`,...
ORM将数据库表映射为PHP类,表中的每一行对应类的一个实例,而表的列则对应类的属性。这样,我们可以使用类的方法(如set和get)来操作数据,而不是直接操作SQL。 在给定的例子中,有一个名为`TbUser`的表,我们...
Sworm是一个基于Swoole的异步MySQL调用的ORM数据库框架。该框架封装了swoole_mysql,API与NotORM很相似。使用Sworm能更加轻松地生成查询语句,使代码结构更加清晰,返回更加规范。
8. **代码生成工具**:除了JSON生成PHP Class,还有其他类似的工具,例如从数据库模式生成ORM(对象关系映射)类,或者从接口定义生成客户端代码。 总之,这个工具旨在帮助PHP开发者更高效地处理JSON数据,通过自动...
PHP ORM(Object-Relational Mapping)是一种编程技术,它允许开发者在面向对象的编程中处理数据库操作,通过映射数据库表结构到PHP类,使得数据操作更加直观和高效。在标题提到的“PHP ORM-开源”项目中,我们可以...
Laravel框架是一款基于PHP的开源Web应用框架,使用了MVC架构模式,其核心功能之一是Eloquent ORM,这是一种优雅简洁的Active Record实现。在实际应用开发中,我们经常会遇到需要根据多个条件组合查询数据库的情况,...
在内置的基础上进行增强抽象,更加轻便的封装方式使代码更加高效。现独立出来方便自己在多个项目中使用同一套类库,同样也提供给有需要的同学。 安装 composer require famio/pour 说明 文件夹&文件 /src/Base为...
8. **示例文件**:压缩包中的文件如`creat.php`、`page.php`、`delete.php`、`query.php`、`insert_id.php`、`insert.php`、`update.php`可能是示例脚本,展示了如何使用这个数据链接类进行创建表、分页查询、删除...
在PHP编程中,类是面向对象编程的基础,它封装了数据和操作这些数据的方法,使得代码更加模块化、可重用。"php常用类实用型高.方便使用"这个标题暗示了我们讨论的是PHP中的一些常见且实用的类库,它们能够提高开发...
8. **ORM支持**:为了进一步降低学习成本,我们还实现了一种简单的对象关系映射(ORM),允许开发者用类和对象的方式来操作Elasticsearch中的文档。 通过这些改进,我们的封装不仅提高了开发效率,也降低了团队成员...
在IT行业中,PHP是一种广泛应用的开源脚本语言,...在实际项目中,开发者可以根据需求选择合适的类进行集成,以实现功能需求。这份2011年的php常用类集合,虽然时间稍早,但其中的许多设计理念和技术仍然具有借鉴价值。
1. `src` 目录:包含了实现Swoole ORM的核心代码,可能有数据库连接管理类、查询构造器、事务处理等功能。 2. `example` 目录:提供了一些示例代码,展示如何在实际项目中使用这个ORM库。 3. `config` 目录:可能...