PHP数据对象映射模式与实现简单的链式操作

**

一、数据对象映射模式

**

什么是数据对象映射模式?这个模式其实不太常用,但是既然学到了,那就写写呗。

数据对象映射模式,就是将对象和数据存储映射起来,对一个对象的操作会映射为对数据存储的操作,数据映射模式使您能更好的组织你的应用程序与数据库进行交互。大家如果用过 thinkphp 这个框架,应该知道里面的 Model 吧,当你 new User(或 $user = M(‘User’)) 的时候,其实就是在操作 user 表了有没有,这里要说的这个模式,实现的功能跟这个场景差不多(目前我没看过thinkphp源码,不知道是不是应用了这个模式)。

1、数据表

在这里为了试验,我们先建 test 数据库,在里面添加一张 user 表:

#创建test数据库
CREATE DATABASE test;

USE test;

#创建user表
CREATE TABLE user(
    id INT(11) PRIMARY KEY AUTO_INCREMENT,
    name CHAR(20),
    mobile INT(11), 
    regtime TIMESTAMP
);

#插入测试数据
INSERT INTO user(name,mobile,regtime) VALUES('lsgozj',12345678910,NOW());

创建如图:
PHP数据对象映射模式与实现简单的链式操作_第1张图片

2、实现数据对象映射模式:

在这里我们建立 User 类来对应 user 表:

class User
{
    //分别对应User表里面的四个字段
    public $id;
    public $name;
    public $mobile;
    public $regtime;

    //保存数据库连接
    private $db;

    function __construct($id)
    {
        $this->db = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'zhongjin');
        $res = $this->db->query("SELECT * FROM user WHERE id={$id} LIMIT 1");
        $data = $res->fetch(PDO::FETCH_ASSOC);
        $this->id = $data['id'];
        $this->name = $data['name'];
        $this->mobile = $data['mobile'];
        $this->regtime = $data['regtime'];
    }

    function __destruct()
    {
        $sql = "UPDATE user SET name=?,mobile=?,regtime=? WHERE id=? LIMIT 1";
        $res = $this->db->prepare($sql);
        $res->execute(array($this->name, $this->mobile, $this->regtime, $this->id));
    }
}

以上代码就是一个简单的实现数据对象映射的例子(对类操作映射到对数据库的操作)。从代码中可以看出,我们只有构造函数和析构函数,构造函数用来获取用户的信息,而析构函数用来保存修改的信息(由于析构函数是在对象被销毁的时候调用,默认是在脚本执行完后销毁对象,所以如果你需要在脚本完成前将修改的值存入数据库,那可能就要手动销毁对象了);

现在我们在客户端中使用该模式:

class Client
{
    static function Main($id)
    {
        $user = new User($id);
        //获取用户数据
        var_dump($user->id,$user->name,$user->mobile,$user->regtime);
        //修改用户数据
        $user->name = 'lsgozhongjin';
        $user->mobile = "12345678912";
        $user->regtime = date('Y-m-d H:i:s', time());
    }
}

//调用客户端
Client::Main(1);

现在你去数据库中查看一下是不是里边的数据已经发生了变化?

使用该模式就简化了对数据库表的操作,比如有个合作伙伴对sql语句不太熟悉,那么使用该模式就使得他根本不用担忧自己要写sql语句了。

**

实现简单的链式操作

**

1、链式操作:

如果用过 thinkphp 的伙伴都应该知道,我们查询修改数据表信息的时候是不是都这样:

$user = M('User');
$where = array('name' => 'zhongjin','age' => 20);
$order = array('id'=>'desc','name');
$res = $user->where($where)->order($order)->select();

其实这里用的就是PHP的链式操作。

2、实现

实现PHP的链式操作的最关键的一步是:在不是最后一步的操作函数中必须 return $this,即返回本对象,以调用后续的方法和使用。

User类:

class User
{
    private $db;
    private $where = array();
    private $order = array();

    function __construct()
    {
        $this->db = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'zhongjin');
    }

    function where(array $where)
    {
        $this->where = $where;
        //不是最后操作,return $this
        return $this;
    }

    function order(array $order)
    {
        $this->order = $order;
        //不是最后操作,return $this
        return $this;
    }

    function select()
    {
        $sql = "SELECT * FROM user";
        if(!empty($this->where)){
            $sql .= ' WHERE ';
            foreach ($this->where as $key => $val) {
                //在查询条件中,如果是数字就不用加引号
                if (is_numeric($val)) {
                    $sql .= $key . "=" . $val . " AND ";
                } else {
                    $sql .= $key . "='" . $val . "' AND ";
                }
            }
            $sql = substr($sql, 0, strlen($sql) - 5);
        }

        if(!empty($this->order)){
            $sql .= ' ORDER BY ';
            foreach($this->order as $key => $val){
                if(is_numeric($key)){
                    //如果键是数字,那么默认是升序 asc
                    $sql .= $val.' ASC,';
                }else{
                    $sql .= $key.' '.strtoupper($val).',';
                }
            }
            $sql = substr($sql, 0, strlen($sql) - 1);
        }


        //echo $sql;
        $res = $this->db-> query($sql);
        $data = $res->fetchAll(PDO::FETCH_ASSOC);
        return $data;
    }
}

客户端调用:

class Client
{
    static function Main()
    {
        $user = new User();
        $where = array('name' => 'lsgozj', 'mobile' => 12345678910);
        $order = array('id'=>'desc','name');
        $res = $user->where($where)->order($order)->select();

        //这时候的sql语句是:SELECT * FROM user WHERE name='lsgozj' AND mobile=12345678910 ORDER BY id DESC,name ASC

        var_dump($res);
    }
}

Client::Main();

以上就是我实现的简单的PHP链式操作,代码非常的简陋(例如where中的大小比较就没有考虑)。由于没有看过thinkphp源代码,不知道人家是怎么实现的,但我感觉思想应该是差不多的。

以上的内容都是本人在观看慕课网中的《大话PHP设计模式》中的实践代码与心得,希望得到大家的指正和建议。

你可能感兴趣的:(php,设计模式,php,php设计模式)