Symfony2 bundle继承丢失父包路由

时间:2012-02-21 06:57:12

标签: php symfony routing annotations

我正在尝试按照here中的说明创建一个简单的bundle继承,并遇到路由问题。我正在使用注释进行路由。当我在AppKernel.php中注册我的子包时,我的所有父包路由都将丢失。

根据我从文档中理解的内容,Symfony2应首先从子包中查找所有文件,包括路由,然后从父包中查找。现在没有发生,只有子捆绑控制器似乎被加载。

在我的子包Bundle文件中,我按照指示实现了getParent函数,在我的routing.yml中我有:

ParentBundle:
resource: "@Parent/Controller/"
type:     annotation
prefix:   /admin/

在继承之前工作正常。

我已经测试过系统工作正常如果在routing.yml中包含所有控制器文件,但这似乎是非常麻烦的方式使继承工作,因为我只想覆盖父包的几个部分(不是所有控制器) )。

Profiler将我的两个捆绑包显示为活动状态。

4 个答案:

答案 0 :(得分:18)

我找到了解决此问题的正确方法。今天我还试图覆盖配置了注释路由的父包,并且如果anotation routing导入整个包(“@ SomeBundle / Controller”),也发现父路由被忽略。

经过一些调试后,我发现对此的解释是,如果你使用“@”作为控制器的前缀,这将传递给内核解析器,如果父资源被覆盖,它将仅返回子资源。因此,解决方案是提供捆绑包的完整路径,考虑到内核将尝试匹配来自 app / Resources 的资源,因此您必须添加相对目录(../../) )在实际路径之前:

# app/config/routing.yml:
some_parent:
    resource: "../../src/Application/ParentBundle/Controller"
    type: annotation

# ChildBundle implements getParent() method to inherit from ParentBundle
some_child:
    resource: "@ChildBundle/Controller"
    type: annotation

这将按预期工作:将导入所有父路由,并将被子包中指定的所有路由覆盖。

答案 1 :(得分:10)

除了之前的回答,我还必须更改子包的routing.yml的名称(例如,更改为routing_child.yml)以使其正常工作。我假设这是因为如果名称相同,Symfony完全忽略父包路由文件。

编辑: 在许多情况下,将父包路由导入子包路由文件也是可行的,如下所示:

# routing_child.yml     
_parent:
    resource: "@MyParentBundle/Resources/config/routing.yml"

答案 2 :(得分:2)

官方文档说您只需将父路由文件复制到您的子包:

  

“覆盖”捆绑包路由的最简单方法是永远不会导入它。不要导入第三方软件包的路由,只需将该路由文件复制到您的应用程序中,修改它,然后将其导入。

此外,您不能使用符号名称“@ParentBundle”包含父代的捆绑路由文件,因为此名称已解析为“@ChildBundle”。

如果你真的想要包含父路由文件,那么你应该使用该文件的绝对路径或相对于当前目录的路径,即:

# @YourChildBundle/Resources/routing.yml
YourParentBundle:
  resource: "/srv/www/example.com/src/Your/ParentBundle/Resources/routing.yml"

# @YourChildBundle/Resources/routing.yml
YourParentBundle:
  resource: "../../../../../Your/ParentBundle/Resources/routing.yml"

另一种解决方法是将您的父路由文件符号链接到您的子包中,并将其包含在更短的路径中,即:

cd YourChildBunde
ln -s ../../../../../Your/ParentBundle/Resources/routing.yml parent_routes.yml

然后

# @YourChildBundle/Resources/routing.yml
YourParentBundle:
  resource: "parent_routing.yml"

P.S。我希望他们能找到一些更好,更简单的方法来覆盖和扩展父包的路由,但现在我们必须解决一些丑陋的解决方法。

答案 3 :(得分:0)

使用bundle继承,您可以覆盖父包的文件。

如果在捆绑包中的父项所在的位置创建路由文件(如果父文件的路由位于ParentBundle / Resources / config / routing.yml,则在ChildBundle / Resources /创建路由文件config / routing.yml),它将覆盖父路由的routing.yml,而symfony只会使用子路由的routing.yml。

我还没试过,但是如果你在子包的routing.yml中导入父包的routing.yml,你可以解决你的问题。由于Symfony路由器将始终选择它找到的第一个匹配路由,您可以通过在导入代码之上写入相关路由代码来覆盖您想要的特定路由。