Symfony2 包继承丢失父包路由

发布于 2025-01-07 17:35:59 字数 583 浏览 0 评论 0原文

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

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

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

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

在继承之前工作正常。

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

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

I am trying to create a simple bundle inheritance as instructed in here and ran into a problem with routes. I'm using annotations for routing. When I register my child bundle in AppKernel.php all my parent bundles routes are lost.

For what I understand from the documentation Symfony2 should look all files, including routes, first from the child bundle and then from the parent bundle. Now that is not happening, only child bundles controllers seems to be loaded.

In my child bundles Bundle file I have implemented getParent function as instructed, and in my routing.yml I have:

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

which worked fine before the inheritance.

I have tested that the system works fine if in include all controller files separetely in routing.yml but that seems very cumbersome way to make the inheritance to work as I only want to override few parts of the parent bundle ( not all controllers ).

Profiler is showing both of my bundles as active.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

伪心 2025-01-14 17:35:59

我找到了解决这个问题的正确方法。今天,我还尝试覆盖配置有注释路由的父包,并且还发现如果注释路由导入整个包(“@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

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

I found the right solution for this issue. Today I was also trying to override a parent bundle configured with annotations routing and also found that parent routes were ignored if the anotation routing imported the whole bundle ("@SomeBundle/Controller").

After a little debugging I found that the explanation for this is that if you use "@" as prefix for the controller this will pass to the kernel resolver which will return ONLY the child resource if the parent resource has been overridden. So the solution is to provide the full path of the bundle, considering that the kernel will try to match the resource from app/Resources so you will have to add a relative directory (../../) before the actual path:

# 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

This will work as expected: all parent routes will be imported and will be overridden by all routes specified in the child bundle.

难如初 2025-01-14 17:35:59

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

编辑:
在许多情况下,将父包路由导入到子包路由文件中也很实用,如下所示:

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

In addition to previous answer, I also had to change the name of the routing.yml of the child bundle (e.g. to routing_child.yml) to get it working. I assume this is because Symfony totally ignores the parent bundle routing file if the name is identical.

EDIT:
In many cases it's also practical to import parent bundle routes into the child bundle routing file like this:

# routing_child.yml     
_parent:
    resource: "@MyParentBundle/Resources/config/routing.yml"
七禾 2025-01-14 17:35:59

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

“覆盖”包的路由的最简单方法是根本不导入它。无需导入第三方包的路由,只需将该路由文件复制到您的应用程序中,修改它,然后导入即可。

此外,您不能使用符号名称“@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.我希望他们能找到一些更好、更不丑陋的方法来覆盖和扩展父包的路由,但现在我们必须找到一些丑陋的解决方法。

The official documentation says that you shall just copy parent routing file to your child bundle:

The easiest way to "override" a bundle's routing is to never import it at all. Instead of importing a third-party bundle's routing, simply copying that routing file into your application, modify it, and import it instead.

Also, you cannot include parent's bundle routing file using symbolic names "@ParentBundle" because this name is resolved to "@ChildBundle".

If you really want to include parent routes file, then you shall use the absolute path to that file or path relative to current directory, i.e.:

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

or

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

Another workaround is to symlink your parent routing file into your child bundle and include it with shorter path, i.e.:

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

and then

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

P.S. I hope they'll find some better and less uglier way to override and extend routing from parent bundle, but now we have to se some of those ugly workarounds.

笑梦风尘 2025-01-14 17:35:59

通过包继承,您可以覆盖父包的文件。

如果您在与包中的父级相同的位置创建路由文件(如果父级文件的路由位于 ParentBundle/Resources/config/routing.yml,并且您在 ChildBundle/Resources/config/routing 处创建路由文件.yml),它将覆盖父级的routing.yml,并且symfony将仅使用子级的routing.yml。

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

With bundle inheritance, you can override the parent bundle's files.

If you create a routing file in the same location as the parents in your bundle (if the routing of the parent file is at ParentBundle/Resources/config/routing.yml, and you create a routing file at ChildBundle/Resources/config/routing.yml), it will override the parent's routing.yml, and symfony will only use the child's routing.yml.

I haven't tried, but if you import the parent bundle's routing.yml in the child bundle's routing.yml, you can solve your problem. As Symfony router will always choose the first matching route it finds, you can override the specific route you want by writing the relevant routing code on top of the import code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文