6

我正在扩展现有的 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()其他任何东西。
  • 如果它有一些触发支持(例如beforeSaveafterSave),则加分。不是要求,但很高兴拥有。

编辑:有人让我摆脱了痛苦。我刚刚发现 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;
}

欢迎任何提示甚至替代解决方案!

4

2 回答 2

11

我用... http://github.com/j4mie/idiorm/

它也以巴黎的形式进行了积极的记录实施。

关于您的编辑。Idiorm 可以应对不断变化的模式,并且语法几乎与您在问题中想要的类型完全匹配。

于 2011-01-18T10:03:58.017 回答
1

您对 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();
于 2011-01-18T10:26:17.683 回答