繁体   English   中英

在Symfony2中干净地扩展Propel模型的策略?

[英]Strategies for cleanly extending Propel Models in Symfony2?

我想做这个:

// 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 over Doctrine,但是这样的事情让我觉得Propel不适合超过一定规模的项目......

(Propel 1.6 + Symfony 2.3 btw)

我是GlorpenPropelBundle的创造者,所以我想我可以解决一些问题:)

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

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

如果您只想向供应商捆绑模型添加一些方法,那么您就不走运了。 在过去,有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 {...}

你已经和问过的问题是你已经写过关于构建时/运行时的问题。 由于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查询语句参考文档 -向下滚动到最后一刻

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM