【问题标题】:Strategies for cleanly extending Propel Models in Symfony2?在 Symfony2 中干净地扩展 Propel 模型的策略?
【发布时间】:2013-07-22 23:21:37
【问题描述】:

我想这样做:

// Model class
namespace Bookshop\Inventory\Model;
use Core\Inventory\Model\Product as BaseProduct;

class Book extends BaseProduct { 
    // ... 
}


// Query class
namespace Bookshop\Inventory\Model;
use Core\Inventory\Model\ProductQuery as BaseProductQuery;

class BookQuery extends BaseProductQuery { 
    // ... 
}

看起来不错,对吧?但是:

$book = BookQuery::create()->find($id);
var_dump(get_class($book));
// expected: Bookshop\Inventory\Model\Book
// actual:   Core\Inventory\Model\Product

AFAIK 这是因为 Propel 的关系是在构建时定义的,而不是运行时...我发现实现这一点的唯一方法是使用 GlorpenPropelBundle 中的扩展行为并定义扩展我的配置中的类:

glorpen_propel:
    extended_models:
        Core\Inventory\Model\Product: Bookshop\Inventory\Model\Book

很好,它有效,但肯定有更好的方法吗?我错过了什么,或者这真的是在 Propel + Symfony 中扩展模型的唯一方法吗?我真的很想使用 Propel 而不是 Doctrine,但是这样的事情让我觉得 Propel 根本不适合超过一定规模的项目......

(Propel 1.6 + Symfony 2.3 顺便说一句)

【问题讨论】:

  • 我怀疑 GlorpenPropelBundle 是您最好的选择。我遇到了无法扩展 Propel 模型的类似问题,通常我所做的是添加一个新类,该类在构造函数中采用基本模型。然后在查询类中,我们只获取原始模型,然后包装它们并返回它们。

标签: php symfony architecture doctrine-orm propel


【解决方案1】:

我是 GlorpenPropelBundle 的创建者,所以我想我可以对问题有所了解:)

Propel 确实提供了用于修改的模型类,但遗憾的是,在使用它们自己的模型谈论外部 Bundle 时,类是在它们内部生成的。没有二级用户类。

在某些情况下,您可以使用 Propel 单继承行为 - http://propelorm.org/documentation/09-inheritance.html 或 hakre 提供的解决方案。

如果您想简单地向 vendor 捆绑模型添加一些方法,那么您就不走运了。 过去有 http://trac.symfony-project.org/wiki/HowToExtendPropelPluginModel,但现在在某些情况下它不起作用 - 这就是我的捆绑包起作用的地方。

如果你在自己的应用程序中,你总是可以通过以下方式进行类扩展(因为 Propel 用户类只生成一次):

namespace Bookshop\Inventory\Model;
//your custom class extending Propel base class
class Book extends \Core\Inventory\Model\om\BaseProduct { ... }

namespace Core\Inventory\Model;
//propel user class extending your custom class
class Book extends Bookshop\Inventory\Model\Book {...}

【讨论】:

  • +1 加入并留下答案,在 WE 上没有看到。谢谢。
【解决方案2】:

您遇到并询问的问题是您已经写过关于构建时/运行时的问题。由于BookQuery::create() 是一个静态方法,它会将模型类名解析为BaseProduct

Propel 手册中也对此进行了概述:

由于 PHP 5.2 中的后期静态绑定问题,您不能在继承查询中使用 create() 工厂 - 除非您自己在后代类中覆盖它。或者,Propel 提供了一个名为 PropelQuery 的全局查询工厂:

<?php
// Use 'frontendBook' instead of 'Book' in the frontend to retrieve only 
// published articles
$books = PropelQuery::from('frontendBook')->find();

来源:Propel Query ReferenceDOCS - 向下滚动到 非常 端。

所以要么覆盖它,要么指定它。

我希望这可以解决您的问题,因为它允许您指定 propel 使用的查询以及实体类。

顺便说一句,Glorpen Propel Bundle 采用了不同的方法,更改了为静态 getOMClass 方法执行的代码。这闻起来像我鼻子里的一个黑客,但我现在判断还为时过早。您可以在Behaviors/ExtendBehavior.php 中找到代码。

【讨论】:

    猜你喜欢
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2014-01-15
    • 1970-01-01
    • 2014-09-23
    • 2023-03-04
    • 1970-01-01
    相关资源
    最近更新 更多