`

PHP ORM类进行封装

阅读更多

基于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 封装

    codeigniter 3.X的ORM 设计,方便大家使用。您也可以前往composer下载:PHP kichijyo/codeigniter3.x_orm_model,具体使用说明请参考composer的markdown文本。命令:composer require kichijyo/codeigniter3.x_orm_...

    php数据库访问封装类集合

    总结来说,“php数据库访问封装类集合”是一个包含多种数据库访问实现的资源,可以帮助PHP开发者更方便地进行数据库操作。通过理解并运用这些封装类,我们可以提高代码的效率和安全性,同时降低维护成本。

    ORM映射与WEB的应用

    ORM的核心思想是通过创建一个映射文件或使用注解,将数据库的表与程序中的类关联起来,每个表对应一个类,表中的字段对应类的属性。这样,当我们在程序中操作对象时,实际上是在操作数据库中的数据,反之亦然。ORM...

    PHP ORM(面向对象PDO数据库框架&amp;API框架)

    自主封装的PHP ORM框架,面向对象的PDO数据库操作,API框架,支持Get/Post/Put/Delete多种请求方式。 代码示例: &lt;?php use Models\User; require '../application.php'; require '../loader-api.php'; //适合...

    PHP开源链式代码封装、数组、字符串、验证

    PHP提供了丰富的数组函数,如`array_push`、`array_pop`、`array_map`、`array_filter`等,用于对数组进行各种操作。例如,我们可以使用`array_map`函数将数组中的所有元素转换为大写: ```php $array = ['hello',...

    一些可用的php类(几乎涵盖了所有php类)

    13. **对象-关系映射(ORM)类**:简化数据库操作,如Doctrine、Eloquent等。 14. **模板渲染类**:如Twig、Smarty,用于动态生成HTML页面。 15. **图像处理类**:如GD库或Imagick,支持图片的裁剪、缩放、水印等...

    PHP常用类大全,高效开发必备

    同时,利用`Error`类和`ErrorException`类进行更精细的错误控制。日志记录类则可以帮助开发者将错误信息或调试信息记录到文件,如自定义的日志类,集成`error_log()`函数。 2. **字符串操作**:PHP提供了`String`类...

    php实现mysql封装类示例

    在PHP中,MySQL封装类是一种常见的做法,它允许开发者将与数据库交互的代码集中在一个类中,从而提高代码的可读性、可维护性和复用性。以下是一个PHP实现的MySQL封装类的详细解析: 首先,我们看到类名为`Mysql`,...

    PHP基于ORM方式操作MySQL数据库实例

    ORM将数据库表映射为PHP类,表中的每一行对应类的一个实例,而表的列则对应类的属性。这样,我们可以使用类的方法(如set和get)来操作数据,而不是直接操作SQL。 在给定的例子中,有一个名为`TbUser`的表,我们...

    Sworm基于Swoole的异步MySQL数据库ORM框架

    Sworm是一个基于Swoole的异步MySQL调用的ORM数据库框架。该框架封装了swoole_mysql,API与NotORM很相似。使用Sworm能更加轻松地生成查询语句,使代码结构更加清晰,返回更加规范。

    一个使用json生成phpclass代码的工具

    8. **代码生成工具**:除了JSON生成PHP Class,还有其他类似的工具,例如从数据库模式生成ORM(对象关系映射)类,或者从接口定义生成客户端代码。 总之,这个工具旨在帮助PHP开发者更高效地处理JSON数据,通过自动...

    货拉拉SDK开放平台php版本SDK封装案例thinkphp和yaf框架下载(亲测100%可用)

    ### 货拉拉SDK开放平台php版本SDK封装案例thinkphp和yaf框架解析 #### 一、货拉拉SDK开放平台概述 货拉拉SDK开放平台为开发者提供了丰富的接口和工具,支持多种语言和框架,其中php版本的SDK特别适用于基于PHP语言...

    PHP ORM-开源

    PHP ORM(Object-Relational Mapping)是一种编程技术,它允许开发者在面向对象的编程中处理数据库操作,通过映射数据库表结构到PHP类,使得数据操作更加直观和高效。在标题提到的“PHP ORM-开源”项目中,我们可以...

    Laravel Eloquent ORM 多条件查询的例子

    Laravel框架是一款基于PHP的开源Web应用框架,使用了MVC架构模式,其核心功能之一是Eloquent ORM,这是一种优雅简洁的Active Record实现。在实际应用开发中,我们经常会遇到需要根据多个条件组合查询数据库的情况,...

    倒入:实用型PHP库,包括针对LaravelLumen,ORM,GuzzleHttp以及源生PHP7 +的扩展支持。在内置的基础上进行增强抽象,更轻便的封装方式使构建代码更加高效

    在内置的基础上进行增强抽象,更加轻便的封装方式使代码更加高效。现独立出来方便自己在多个项目中使用同一套类库,同样也提供给有需要的同学。 安装 composer require famio/pour 说明 文件夹&文件 /src/Base为...

    DL php数据链接类

    8. **示例文件**:压缩包中的文件如`creat.php`、`page.php`、`delete.php`、`query.php`、`insert_id.php`、`insert.php`、`update.php`可能是示例脚本,展示了如何使用这个数据链接类进行创建表、分页查询、删除...

    php常用类实用型高.方便使用

    在PHP编程中,类是面向对象编程的基础,它封装了数据和操作这些数据的方法,使得代码更加模块化、可重用。"php常用类实用型高.方便使用"这个标题暗示了我们讨论的是PHP中的一些常见且实用的类库,它们能够提高开发...

    对新版的elasticsearch-php做进一步的封装,使其更贴近mysql的相关操作,减少大家的学习成本.zip

    8. **ORM支持**:为了进一步降低学习成本,我们还实现了一种简单的对象关系映射(ORM),允许开发者用类和对象的方式来操作Elasticsearch中的文档。 通过这些改进,我们的封装不仅提高了开发效率,也降低了团队成员...

    2011年php常用类集合

    在IT行业中,PHP是一种广泛应用的开源脚本语言,...在实际项目中,开发者可以根据需求选择合适的类进行集成,以实现功能需求。这份2011年的php常用类集合,虽然时间稍早,但其中的许多设计理念和技术仍然具有借鉴价值。

    swoole-orm-master.zip

    1. `src` 目录:包含了实现Swoole ORM的核心代码,可能有数据库连接管理类、查询构造器、事务处理等功能。 2. `example` 目录:提供了一些示例代码,展示如何在实际项目中使用这个ORM库。 3. `config` 目录:可能...

Global site tag (gtag.js) - Google Analytics