Symfony2 - 针对不同内容类型的根slu ..

时间:2015-04-15 16:21:21

标签: php symfony routing

我希望有多条路线只有一条路径" part"在URI中,但加载不同类型的内容。

例如,我希望通过/page-slug-here加载使用CMS创建的页面。不过,我还希望通过/product-slug-here加载产品,通过/category-slug-here加载的类别,通过/brand-slug-here加载的品牌等等。

使用Symfony2实现这一目标的最佳/最具活力的方法是什么,当没有找到他们各自的内容时,没有复杂(且效率低)的控制器链转发到下一个操作?< / p>

我还想避免使用单一操作来检查每种类型的内容。

2 个答案:

答案 0 :(得分:1)

您可以拦截请求并使用自己的路由器侦听器发挥魔力。

我自己没有测试过,但我只是想指出你正确的方向。

在service.xml文件中,您可以添加以下内容:

    <parameters>
        <parameter key="my.router_listener.class">MyBundle\Listener\RouterListener</parameter>
    </parameters>

    <services>
        <service id="my.router_listener" class="%my.router_listener.class%">
            <argument type="service" id="doctrine.orm.entity_manager" />
            <tag name="kernel.event_subscriber" priority="33" />
        </service>
    </services>

这里的优先事项很重要。 32是默认路由器。你想成为它的忠诚。 http://symfony.com/doc/current/reference/dic_tags.html

然后像这样创建服务:

class DynamicRouterListener extends RouterListener
{
    private $entityManager;

    public function __construct(EntityManager $entityManager)
    {
        //...
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        $request = $event->getRequest();
        $path = $request->getPathinfo();

        // Some magic here
        if(// magic is true) {
            $request->attributes->set('_controller', 'MyBundle:MyController:myAction');
        }
    }
}

接下来的默认路由器将看到_ controller参数已存在,并将跳过与dafult规则的匹配。

答案 1 :(得分:-1)

我认为你不能完全或没有碰撞的风险。

您需要能够告诉路由器您指的是哪种东西,或者它无论如何都不知道它是产品,页面还是品牌。至少,您需要手动避免名称冲突。

您可以使用匹配的模式设置3条路线,如下所示:

/**
 * @Route("/{page-slug}")
 *
 *
 * @Method("GET")
 */
public function pageAction(PageClass $page)
{
     ...
}

但你无法决定首先在路由器内匹配哪些尝试;所以,如果发生碰撞,你基本上都是搞砸了。