现有 PHP 应用程序需要一个简单的 ORM 或 DBAL
Posted
技术标签:
【中文标题】现有 PHP 应用程序需要一个简单的 ORM 或 DBAL【英文标题】:Need a simple ORM or DBAL for existing PHP app 【发布时间】:2011-06-10 22:37:05 【问题描述】:我正在扩展现有的 php 应用程序。对我来说不幸的是,现有的应用程序一团糟。这都是带有原始 mysql_* 调用的意大利面条代码。呻吟。我不会在我正在扩展的部分中这样做。
所以,我正在寻找一个简单的 DBAL ORM,我可以轻松放入并开始使用。所需功能:
它必须适用于现有的数据库模式。最好有最少的或没有额外的配置。现有的数据库模式与现有的 PHP 代码质量相同(没有合理的命名约定,没有规范化等)。我不想像 Doctrine 2 那样花几天时间手动将数据库模式转换为带注释的对象属性。 它必须能够与现有的原始 mysql_* 查询一起工作。我不知道当脚本在背后手动操作数据库中的数据时,像 Doctrine 2 或 Propel 这样的水合 ORM 的行为如何,但我认为它并不漂亮。 它必须在 PHP 5.2.x 上运行。我喜欢使用 PHP 5.3,但我对检查现有的 125K 行意大利面条代码混乱以确保它在 PHP 5.3 上运行毫无兴趣。 不需要关系。在我需要访问关系数据的少数几个地方,我很乐意额外拨打find()
或query()
或我自己的电话。
如果它有一些触发器支持(例如beforeSave
、afterSave
),则可以加分。不是必需的,但很高兴拥有。
编辑:有人让我摆脱了痛苦。我刚刚发现 125K 行意大利面条代码也改变了数据库模式。例如,在某处添加一个额外的选项,大量的 ALTER TABLE 语句开始运行。我可能可以用这个代码库填满一年的 TheDailyWTF。所以,还有一个要求:
必须能够自动应对不断变化的数据库架构(例如添加列)。我一直在寻找一些解决方案,但我不确定在满足要求的情况下它们的效果如何。 Doctrine 2、RedBeanPhp 之类的都需要 PHP 5.3,所以它们被淘汰了。有用于 PHP 5.2.x 的 RedBeanPhp 的旧版本,但我不知道它是否适用于混乱的现有数据库模式。 NotORM 在获取数据方面看起来不错,但我不知道它是否可以针对现有的数据库模式进行配置,以及如何轻松地将数据放回数据库中。
理想情况下,我想要一些简单的东西。例如:
$user = User::find($id);
$user->name = 'John Woo';
$user->save();
或者:
$articles = ORM::find('article')->where('date' => '2010-01-01');
foreach ($articles as $article)
echo $article->name;
欢迎任何提示甚至替代解决方案!
【问题讨论】:
【参考方案1】:我用... http://github.com/j4mie/idiorm/
它也有一个活跃的记录实现,以巴黎的形式。
关于您的编辑。 Idiorm 可以应对不断变化的模式,语法几乎与您在问题中想要的类型完全匹配。
【讨论】:
我已经在应用程序中使用 Idiorm 和 Paris 几个星期了,我非常喜欢它!【参考方案2】:您对 Doctrine 的看法如何?我正在使用 Doctrine 1.2 来处理这些事情。非常容易设置,允许您从现有模式开始。它会自动找出具有外键约束的表之间的关系。
它具有广泛的触发和行为支持,因此可以使用奖励积分,并且它还具有关系支持,因此您不需要额外的查询。它具有漂亮的延迟加载功能,并带有一种灵活的查询语言(称为 DQL),它允许您执行几乎与在 SQL 中可以执行的操作完全相同的操作。
您的示例将如下所示:
/* To just find one user */
$user = Doctrine::getTable('User')->findOneById($id);
/* Alternative - illustrating DQL */
$user = Doctrine_Query::create()
->from('User u')
->where('u.id = ?',array($id))
->fetchOne();
$user->name = 'John Woo';
$user->save();
它必须能够与现有的原始 mysql_* 查询一起工作。我不知道当脚本在背后手动操作数据库中的数据时,像 Doctrine 2 或 Propel 这样的水合 ORM 的行为如何,但我认为它并不漂亮。
嗯,这在技术上是不可能自动管理的; SQL 数据库根本不会将内容推回您的 ORM,因此要更新在后台更改的内容,您需要以一种或另一种方式执行额外的查询。幸运的是,Doctrine 让你很容易做到这一点:
/* @var User $user */
/* Change a user using some raw mysql queries in my spaghetti function */
$this->feedSpaghetti($user->id);
/* Reload changes from database */
$user->refresh();
【讨论】:
但是,当应用程序的其他部分仍然使用原始 mysql_* 调用,更改 Doctrine 背后的数据时会发生什么?或者更糟糕的是,当架构在它脚下发生变化时?就像我说的,该应用程序是 125K 意大利面条代码,背后有一个严重非规范化的数据库。假设最坏的情况。乘以 2。Doctrine 可以处理吗? 不确定您是否已经阅读了我的更新。您确实需要刷新记录,但是,由于 SQL 的性质,在任何 ORM 中都会如此。如果您担心某个 Doctrine 记录过时,只需刷新它,它的字段值就会从数据库中重新获取。以上是关于现有 PHP 应用程序需要一个简单的 ORM 或 DBAL的主要内容,如果未能解决你的问题,请参考以下文章