重定向其他路由尚未限定的任何 URL


Redirecting any URL not already qualified by another route

场景

在我的Symfony2项目中,我有一些基本的路线,如/login/register等。

现在,如果有人出现并试图访问/foo或任何特定路线未处理的任何其他路线,我希望它将他们重定向到/

我的尝试

我有用于/login和其他一些单个 GET 变量路由的路由,使用注释,例如

/**
 * @Route("/login", name="login")
 * @return Response
 * @Template("AccountBundle:login.html.twig")
 */
public function loginAction()
{
    //Code!
}

现在我想有另一个控制器/操作来处理其他任何事情,所以我尝试了

/**
 * @Route("/{some_variable}", name="url_redirect")
 * @param $some_variable string
 * @return 'Symfony'Component'HttpFoundation'Response
 */
public function redirectAction($some_variable = '')
{
    return $this->redirectOldDisciplineUrl($some_variable);
}

问题

当我现在尝试访问/login时,它不会访问登录操作,而是被捕获任何内容的人捕获,并且我被重定向。

问题

如何确保如果我的 GET 变量与特定路由匹配,它会转到该页面,而不是捕获任何内容的页面?

url_redirect路线应该是最后一条。您应该从那里删除@Route注释,并将路由作为最后一个路径放入app/config/routing.yml。或者,您可以为 kernel.exception 事件创建事件侦听器。您可以使用 router:debug 命令检查顺序。

如果这没有回答你的问题,我很抱歉。但我对你的问题有一个想法。如果您的another Controller/Action which handles anything else更改为项目的主控制器,以便您可以检查参数以满足您的需求。我只是认为你可以在这里使用switch case。我不知道如何正确写这个,所以我希望你能理解。

/**
 * @Route("/{some_variable}", name="url_redirect")
 * @param $some_variable string
 * @return 'Symfony'Component'HttpFoundation'Response
 */
public function redirectAction($some_variable)
{
    switch($some_variable){
      case "login": {
        // Your login handler
      },
      case "register": {
        // Your register handler
      },
      default: {
        // Default handler for non-listed route
      }
    }
    return $this->redirectOldDisciplineUrl($some_variable);
}

为什么不覆盖 404 错误处理:

http://symfony.com/doc/current/cookbook/controller/error_pages.html#overriding-the-default-exceptioncontroller

如果你这样做,当你遇到404错误时,你可以做你想做的事,比如处理URL中的数据,开始研究,尝试找出你的访问者试图看到什么......

创建一个新的侦听器:

<?php
namespace YourBundleNameBundle'Bundle'Error404Bundle'Listener;

use Symfony'Component'HttpKernel'Event'GetResponseForExceptionEvent;
use Symfony'Component'HttpKernel'Exception'NotFoundHttpException;
use Symfony'Component'HttpKernel'Log'LoggerInterface;
use Doctrine'ORM'EntityManager;
use Symfony'Component'HttpFoundation'Response;
use Symfony'Component'Templating'EngineInterface;
    class RedirectExceptionListener
    {
        /**
         * @var 'Doctrine'ORM'EntityManager
         */
        protected $em;
        protected $logger;
        protected $templating;
        function __construct(EntityManager $em, LoggerInterface $logger, EngineInterface $templating)
        {
            $this->em = $em;
            $this->logger = $logger;
            $this->templating = $templating;
        }

        /**
         * @param 'Symfony'Component'HttpKernel'Event'GetResponseForExceptionEvent $event
         */
        public function checkRedirect(GetResponseForExceptionEvent $event)
        {
            $exception = $event->getException();
            if ($exception instanceof NotFoundHttpException) {
                // Look for a redirect based on requested URI
                // e.g....
                $uri = $event->getRequest()->getUri();
                $path = $event->getRequest()->getPathInfo();
                //doing stuff ...
                $response = new Response();
                $event->setResponse($this->templating->renderResponse('YourBundleNameBundle:Default:index.html.twig'));
            }
        }
    }

在服务 yml 文件中:

services:
    yourName.exception_listener:
        class: YourClass'Bundle'Error404Bundle'Listener'RedirectExceptionListener
        arguments: ['@doctrine.orm.entity_manager', '@logger', '@templating']
        tags:
            - { name: kernel.event_listener, event: kernel.exception, method: checkRedirect }