认识Marco Pivetta

发布者    |       讨论 Hibernate ORM 访谈

在这篇文章中,我想向大家介绍 Marco Pivetta,他是 Doctrine 的维护者之一,Doctrine 是一套受到 Hibernate ORM 启发的 PHP 项目。

Marco Pivetta, align=

嗨,Marco。你想自我介绍一下并告诉我们一些关于你的开发经验吗?

我是 Marco "Ocramius" Pivetta,一位意大利 PHP 咨询师,目前住在德国。是的,这个昵称很奇怪,但它来自 Quake 3 Arena、Unreal Tournament 等时代。

我从孩提时代就开始摆弄电脑,到现在已经超过一半的时间在用 PHP 开发了,与这个语言有着爱恨交加的关系。有趣的是,我并没有从 Joomla/Wordpress/Drupal 等开始,而是构建了一个相当复杂的网站,该网站与一款名为 "OGame" 的浏览器游戏进行交互,并通过 Firefox 插件抓取游戏信息,然后为玩家提供额外的信息。

这个项目 ("stogame") 对我来说很重要,因为它包含了许多对于没有任何帮助的新手来说极具挑战性的问题,这仍然是我工作过的最复杂的项目之一

  • 跨站脚本/SQL 注入 - 遇到了,不好玩

  • 队列机制以同步浏览器扩展和网站 - 发明了自己的系统

  • 优化 ~60Gb MySQL MyISAM 表的查询和索引

  • 这样系统的灾难恢复 - 也遇到了,也不好玩

  • 通过 BOSHXMPP 为客户端提供实时推送机制

  • 一个简化的预测引擎,以帮助玩家做出决策

以上所有都是 15 岁的我通过无数个不眠之夜构建的,同时也危及了我的学校评估。不过,这还是在库、设计模式、导师、GitHub 之前:只有我、一些朋友,以及大量的设计和预测工作。

然后我继续前进,放弃了这个项目,大学没考上(我是个糟糕的学生),找了几份工作,开始使用框架。最终,我接触到了所有典型的数据库抽象方法

  • 活动记录(使用 ZendFramework)

  • 表数据网关 - 在自定义解决方案中

  • 数据映射器 - 在Java EE项目中

我在Java EE项目中非常喜欢JPA方法,因此我开始寻找一个PHP类似解决方案来处理我的日常工作,最终发现了Doctrine 2。

从那时起,我开始越来越深入地参与项目,从回答邮件列表和StackOverflow上的问题开始。当时项目的负责人Benjamin Eberlei在2011年推动我贡献实际的代码更改。

最终,我成为了项目的维护者之一,这也推动了我的职业生涯,让我成为了Roave的顾问,让我每月都能看到数十个不同的项目、团队和工具,同时也是一名公开演讲者。

您是Doctrine ORM框架的开发者之一。您能告诉我们Doctrine的目标是什么吗?

实际上,我并不是开发者,而是当前的维护者。据我所知,当前Doctrine 2 ORM的最初设计者是Jonathan Wage、Guilherme Blanco、Benjamin Eberlei和Roman Borschel。我可能还能回答这个问题:Doctrine ORM试图将“数据库思维”从PHP软件项目中抽象出来,同时故意成为有漏洞的抽象。

为了澄清,大多数PHP开发者习惯于从数据库层向上开发应用程序,而不是从领域逻辑向下,这是一个相当普遍的问题,导致代码难以维护和阅读。这个工具通过允许开发者在需要时直接访问数据库,消除了大多数这些问题。

Ruby on Rails使用Active Record模式。为什么Doctrine选择ORM范式而不是它?

有趣的是,Doctrine 1.x是一个Active Record库,也是一个相当好的库,但很快就很明显,JPA规范和数据映射加工作单元是更好的整体解决方案。

具体来说,数据映射方法允许库的消费者编写几乎完全解耦工具和领域的抽象(总是存在这种限制)。工作单元模式对PHP应用程序的内存影响更大,但通过内存中的身份映射大大减少了所需的查询操作,并添加了一些事务边界,这对大多数PHP应用程序来说是一个巨大的胜利,因为它们通常甚至根本不使用事务。

还有更多的优点,但我个人永远不会考虑再次使用Active Record,因为它的局限性和固有的框架耦合。这并不意味着Active Record不起作用,但我比DM遇到过更多的问题。

由于Hibernate ORM对Doctrine产生了影响,您能告诉我们这两个框架的相似之处和不同之处吗?

Doctrine深受Hibernate和JPA的启发,尽管由于许可问题和Java和PHP软件的生命周期差异,我们实际上无法复制它们。

Doctrine在单元工作、映射、基本事件系统、二级缓存和DQL语言(Hibernate中的HQL)方面与Hibernate相似。我们甚至为PHP设计了注解系统,因为该语言不支持它们,它目前是PHP库中自定义注解的事实标准,我们最初只需要它来模拟Hibernate允许的内联映射。

在灵活性和生命周期方面有很多不同之处,因为Java是一种AOT编译语言,具有强大的JIT,通常部署在长期运行的应用程序中。

PHP是一种解释型语言,其优点也是其缺点:典型的无共享架构允许运行短生命周期、内存安全、可重试的应用程序。这也意味着我们没有连接池,并且由于内存和执行时间限制,ORM的内部实现比Hibernate更加不灵活,且不如Hibernate以事件驱动。这也意味着由于大型工作单元实例,我们很少遇到内存问题,并且连接和实体实例不会在不同网页加载之间共享,慢速的ORM也不太可能减慢整个应用程序服务器的速度。

另一个巨大的区别是管理状态:在PHP世界中,分离的实体几乎没有意义,因为分离的实体可能仅来自序列化状态。在Doctrine 3.x版本中,我们计划取消对分离实体的支持,因为通常在PHP中存储序列化对象会导致安全问题,并带来更多麻烦。

正如您所看到的,这些差异确实主要在于生命周期,但每种语言和框架都有自己的优点和缺点。

我们始终重视用户的反馈,所以您可以告诉我们您希望我们改进什么,或者有哪些功能是我们应该添加支持的?

我现在可能有点奇怪,但我现在并不缺少任何ORM的特定功能。有趣的是减少对实体和事务生命周期事件的支持,因为这些ORM的大多数消费者倾向于在这些ORM中编写应用程序和领域逻辑,而它们主要被用于技术任务,如创建审计日志和执行预/后数据库清理任务。

一个可能的改进是探索保存/加载与工作单元相关联的单个聚合根实体,这些实体仅负责跟踪子聚合的状态。这样做是为了防止在聚合之间共享实体引用,并防止数据库事务跨越聚合根边界。

感谢Marco抽出时间。能在这里见到您是一种极大的荣幸。要联系Marco,您可以在Twitter上关注他。


返回顶部