Php 学习实现基本ORM的技巧/资源/模式

Php 学习实现基本ORM的技巧/资源/模式,php,database,model-view-controller,orm,Php,Database,Model View Controller,Orm,我在这里看到了各种MVC框架以及PHP的独立ORM框架,以及其他ORM问题;然而,大多数问题都要求现有框架开始使用,这不是我想要的。(我也读过,但我不确定该怎么理解,因为答案很模糊。) 相反,我认为我最好的学习方法是弄脏我的手,并实际编写自己的ORM,即使是一个简单的ORM。除了我真的不知道如何开始,特别是因为我在其他ORM中看到的代码非常复杂 通过我的PHP5.2.x(这很重要)MVC框架,我有一个基本的自定义数据库抽象层,它有: 非常简单的方法,如connect($host,$user,$

我在这里看到了各种MVC框架以及PHP的独立ORM框架,以及其他ORM问题;然而,大多数问题都要求现有框架开始使用,这不是我想要的。(我也读过,但我不确定该怎么理解,因为答案很模糊。)

相反,我认为我最好的学习方法是弄脏我的手,并实际编写自己的ORM,即使是一个简单的ORM。除了我真的不知道如何开始,特别是因为我在其他ORM中看到的代码非常复杂

通过我的PHP5.2.x(这很重要)MVC框架,我有一个基本的自定义数据库抽象层,它有:

  • 非常简单的方法,如
    connect($host,$user,$pass,$base)
    query($sql,$binds)
    ,等等
  • 它支持的每个DBMS的子类
  • 表示SQL结果集的类(以及相应的子类)
但是没有具有:

  • 活动记录功能,我认为这是ORM的东西(如果我错了,请纠正我)
编辑:为了澄清,我只有一个数据库抽象层。我还没有模型,但当我实现它们时,我希望它们是原生ORM模型(可以这么说),因此这个问题

我读过一些关于ORM的书,据我所知,它们提供了一种从数据库本身进一步抽象数据模型的方法,将数据表示为基于PHP的类/对象;同样,如果我错了或以任何方式错过了,请纠正我


不过,我还是想从其他或多或少涉猎过ORM框架的人那里得到一些简单的提示。还有什么我需要注意的,简单的学术样本供我参考,或者我可以阅读的资源吗?

可以使用
\uuuu get()
\uu set()
以及一些自定义方法(可能使用
\uu call()
)构建一个简单的ORM,下面是一个简单的伪代码:

class ORM
{
  private $table = null;
  private $fields = array();

  function __construct($table)
  {
    $this->table = $table;
  }

  function __get($key)
  {
    return isset($this->fields[$key]) ? $this->fields[$key] : false;
  }

  function __set($key, $value)
  {
    $this->fields[$key] = $value;
  }

  function load($id, $field = 'id')
  {
    // populate $this->fields with SELECT * FROM $this->table WHERE $field = $id;
  }

  function save()
  {
    if (isset($this->fields['id']))
    {
      // UPDATE $this->table SET $this->fields;
    }

    else
    {
      // INSERT INTO $this->table $this->fields;
    }
  }
}

$user = new ORM('user');

$user->name = 'name';
$user->pass = '1337';

$user->save();
这只是一个让您开始学习的基本示例。例如,您可以使用
\u call()
magic方法添加进一步的逻辑,以通过
id
以外的其他字段获取结果


请记住,我给出的示例不处理关系,这是各种ORM实现的真正不同之处,但是我通常不相信任何ORM能为我处理关系,因为它们往往速度慢得多,并且不会生成有效的查询。

因为这个问题很老,我想你已经试过自己写ORM了。尽管如此,两年前我写了一个定制ORM,我仍然想分享我的经验和想法

如前所述,我在两年前实现了一个定制的ORM,甚至在中小型项目中成功地使用了它。我将它集成到一个相当流行的CMS中,当时(甚至现在)还没有ORM功能。此外,在当时,像条令这样的流行框架并没有真正说服我。从那时起,很多东西都发生了变化,并在一个坚实的框架中发展,因此,如果我现在可以选择是实现自己的ORM,还是使用一个流行的框架(如条令2)用于生产,这将毫无疑问——使用现有的、稳定的解决方案。但是:实现这样一个框架(以一种简单的方式)是一个非常有价值的学习练习,它对我使用更大的开源ORM有很大帮助,因为您可以更好地理解与对象关系映射相关的陷阱和困难

实现基本的ORM功能并不太困难,但一旦对象之间的关系映射开始发挥作用,它就会变得非常非常困难/有趣


我是如何开始的?

让我上瘾的是马丁·福勒的书。如果您想编写自己的ORM,或者即使您只是在使用某个ORM框架,请购买本书。它是最有价值的资源之一,涵盖了有关对象关系映射领域的许多基本和高级技术。仔细阅读,你会对ORM背后的模式有很多好的想法

基本架构

我决定是采用一种方法还是某种方法。此决策影响数据库中的数据映射到实体的方式。我决定实现一个简单的数据映射器,与Java使用的方法相同。活动记录是ORM功能(如果可以这样称呼的话)的一种方法。Active Record比数据映射器简单得多,但也有很大的局限性。阅读这些模式并检查上面提到的框架,你很快就会发现它们之间的区别。如果您决定使用数据映射器,您还应该仔细阅读

查询

我有一个雄心勃勃的目标,就是创建自己的查询语言,就像在Doctrine或Hibernate中一样。我很快就放弃了这一点,因为编写定制的SQL解析器/词法分析器似乎太复杂了(事实确实如此!)。我所做的是实现一个,以封装查询中涉及的表的信息(这很重要,因为需要将数据库中的数据映射到每个表的相关类)

在我的ORM中查询对象如下所示:

public function findCountryByUid($countryUid) {
    $queryObject = new QueryObject();
    $queryObject->addSelectFields(new SelectFields('countries', '*'))
            ->addTable(new Table('countries'))
            ->addWhere('countries.uid = "' . intval($countryUid) . '"');

    $res = $this->findByQuery($queryObject);
    return $res->getSingleResult();
}
配置

通常,您还需要某种配置格式,Hibernate使用XML(以及其他),Doctrine 2使用PHP注释,EZComponents使用PHP数组作为配置格式。这也是我使用的,它看起来是一个自然的选择,我使用的CMS也使用PHP配置格式

通过该配置,您可以定义

  • 哪个表映射到哪个类
  • 哪些字段应该映射到类实例
  • 表的字段有什么类型(int、string等)
  • 实体之间的关系(例如,用户类具有对用户组类的引用)