4

我想做这个:

// 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 根本不适合超过一定规模的项目......

(推进 1.6 + Symfony 2.3 顺便说一句)

4

2 回答 2

3

我是 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 {...}
于 2013-08-02T10:28:15.293 回答
0

您遇到并询问的问题是您已经写过关于构建时/运行时的问题。作为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 Reference DOCS - 向下滚动到最后

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

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

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

于 2013-08-02T06:42:08.727 回答