gpt4 book ai didi

Symfony2多级动态路由器

转载 作者:行者123 更新时间:2023-12-02 15:58:27 24 4
gpt4 key购买 nike

我当前有一个项目,必须显示具有特定实体的定义页面(使用 Symfony2 很容易管理),以及不同布局上的内容页面(我猜)不太常见。

我在尝试构建路由系统时遇到了麻烦。

例如,如果我必须显示包含一些新闻的页面,我想使用新路由更新我的包的路由器,例如:

my_bundle_news_page:
pattern: /news
defaults:
_controller: MyBundle:NewsController:indexAction

但是如何管理可以在多个级别上拥有完全自定义 URL 的动态路由器呢?

假设我有一个“页面”实体,它是可选“父子”关系的自引用。我不认为我可以使用任何配置 YAML 文件来实现此特定路由?!

my_bundle_custom_page:
pattern: /{slug}
defaults:
_controller: MyBundle:PageController:showAction

这将绑定(bind)所有第一级页面:

/projects

/about

/contact

/our-project

如果页面显示的内容是这样的,例如:

/our-project/health

事实上任何 URL...

/{slug-level1}/{slug-level2}/{slug-level3} etc.

因为页面应该通过网站管理员进行更改和更新。

我想最好的方法是让路由器将 {slug} 与数据库字段(实体属性)进行比较

我读到the Symfony-CMF doc可以编写基于路由提供者的服务:

namespace MyBundle\Routing;

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route as SymfonyRoute;

use MyBundle\Entity\PageRepository;

class RouteProvider extends PageRepository {
public function findPageBySlug($slug)
{
// Find a page by slug property
$page = $this->findOneBySlug($slug);

if (!$page) {
// Maybe any custom Exception
throw $this->createNotFoundException('The page you are looking for does not exists.');
}

$pattern = $page->getUrl(); // e.g. "/first-level/second-level/third-level"

$collection = new RouteCollection();

// create a new Route and set our page as a default
// (so that we can retrieve it from the request)
$route = new SymfonyRoute($pattern, array(
'page' => $page,
));

// add the route to the RouteCollection using a unique ID as the key.
$collection->add('page_'.uniqid(), $route);

return $collection;
}
}

但是如何将其设置为服务呢?有一些要求吗?这种事情是如何工作的,当调用 request 时它会向 RouteCollection 添加路由吗?

我可以通过这种方式绑定(bind)任何路由吗?

编辑:我的包的 services.yml

parameters:
cmf_routing.matcher.dummy_collection.class: Symfony\Component\Routing\RouteCollection
cmf_routing.matcher.dummy_context.class: Symfony\Component\Routing\RequestContext
cmf_routing.generator.class: Symfony\Cmf\Bundle\RoutingBundle\Routing\ContentAwareGenerator
cmf_routing.nested_matcher.class: Symfony\Cmf\Component\Routing\NestedMatcher\NestedMatcher
cmf_routing.url_matcher.class: Symfony\Cmf\Component\Routing\NestedMatcher\NestedMatcher
fsbcms.chain_router.class: Symfony\Cmf\Component\Routing\ChainRouter
fsbcms.route_provider.class: FSB\CMSBundle\Routing\RouteProvider
fsbcms.dynamic_router.class: Symfony\Cmf\Component\Routing\DynamicRouter
fsbcms.route_entity.class: null

services:
fsbcms.router:
class: %fsbcms.chain_router.class%
arguments:
- "@logger"
calls:
- [setContext, ["router.request_context"]]
fsbcms.route_provider:
class: "%fsbcms.route_provider.class%"
arguments:
- "@doctrine"
cmf_routing.matcher.dummy_collection:
class: "%cmf_routing.matcher.dummy_collection.class%"
public: "false"
cmf_routing.matcher.dummy_context:
class: "%cmf_routing.matcher.dummy_context.class%"
public: false
cmf_routing.generator:
class: "%cmf_routing.generator.class%"
arguments:
- "@fsbcms.route_provider"
- "@logger"
calls:
- [setContainer, ["service_container"]]
- [setContentRepository, ["cmf_routing.content_repository"]]
cmf_routing.url_matcher:
class: "%cmf_routing.url_matcher.class%"
arguments: ["@cmf_routing.matcher.dummy_collection", "@cmf_routing.matcher.dummy_context"]
cmf_routing.nested_matcher:
class: "%cmf_routing.nested_matcher.class%"
arguments: ["@fsbcms.route_provider"]
calls:
- [setFinalMatcher, ["cmf_routing.url_matcher"]]
fsbcms.dynamic_router:
class: "%fsbcms.dynamic_router.class%"
arguments:
- "@router.request_context"
- "@cmf_routing.nested_matcher"
- "@cmf_routing.generator"
tags:
- { name: router, priority: 300 }

最佳答案

我建议看一下 Symfony CMF 路由组件和 CmfRoutingBundle(在 symfony 中实现该组件)。

路由组件使用链式路由器,这与这个问题无关,但了解一下还是有好处的。链式路由器链接在路由器队列上。该组件提供了一个使用 NestedMatcher 的 DynamicRouter。这正是您想要的。

NestedMatcher 使用路由提供程序从动态源(例如数据库)获取路由。您在问题中展示了路线提供商的示例。

此外,它使用 FinalMatcher 来匹配路由。您可以只传递 Symfony\Cmf\Component\Routing\NestedMatcher\UrlMatcher 的实例,因为您所做的事情并不是太困难。

看看docs of the RoutingBundle要了解如何激活链路由器,然后创建加载路由的路由提供者,请创建一个服务:

acme_routing.route_provider:
class: Acme\RoutingBundle\Provider\DoctrineOrmProvider
arguments: ["@doctrine"]

现在,您可以创建一个 NestedMatcher 服务:

acme_routing.url_matcher:
class: Symfony\Cmf\Component\Routing\NestedMatcher\UrlMatcher
arguments: ["@cmf_routing.matcher.dummy_collection", "@cmf_routing.matcher.dummy_context"]

acme_routing.nested_matcher:
class: Symfony\Cmf\Component\Routing\NestedMatcher
arguments: ["@acme_routing.route_provider"]
calls:
- [setFinalMatcher, ["acme_routing.url_matcher"]]

现在,注册DynamicRouter并将其放入链中:

acme_routing.dynamic_router:
class: Symfony\Cmf\Component\Routing\DynamicRouter
arguments:
- "@router.request_context"
- "@acme_routing.nested_matcher"
- "@cmf_routing.generator"
tags:
- { name: router, priority: 300 }

现在,它应该可以工作,并且应该从数据库加载路由并将它们与请求进行匹配。

关于Symfony2多级动态路由器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17640099/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com