3

Symfony2 中是否有任何配置允许使用不区分大小写的路由

例如,以下路线应视为相同:

www.exmaple.com/all 
www.exmaple.com/ALL

有一个关于此的拉取请求,但没有参考如何实现它。

4

3 回答 3

2

从 Symfony2.4 开始,您现在可以为您的路由定义条件并使用表达式语言进行复杂检查。请参阅路由器:完全自定义的带有条件的路由匹配文档。

另一种解决方案是覆盖路由编译器类以更改/扩展路由匹配器的 php 编译:

contact:
    path:     /{media}
    defaults: { _controller: AcmeDemoBundle:Main:contact, media: organic }
    requirements:
        media: email|organic|ad
    options:
        compiler_class: MyVendor\Component\Routing\CaseInsensitiveRouteCompiler

参见Symfony\Component\Routing\RouteCompiler类。

或者,正如 fabpot 在拉取请求评论中所说,您可以覆盖 Request::getPathInfo[1] 方法以始终返回小写字符串(使用 setFactory[2] 覆盖默认请求类)。

*1 github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/Request.php#L866

*2 github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/Request.php#L402

于 2014-07-09T18:33:36.527 回答
1

据我所知,这在 Symfony 2 中是不可能的。但是,您应该能够使用 Apache 的 mod_rewrite 来完成它。有关详细信息,请参阅此博客文章

请务必阅读评论,因为初始帖子存在一些错误。

于 2013-07-09T02:25:27.620 回答
1

我发现了一种在纯 symfony(没有 apache mod_rewrite)中执行此操作的绝妙方法,而无需为每条路由创建不区分大小写的转发规则。

这利用了 twig ExceptionController。因为这发生在路由匹配失败(或由于其他原因引发 404 异常)之后,它不会破坏任何使用大写字母的现有路由 url(尽管这仍然是一个坏主意)。

namespace Application\Symfony\TwigBundle\Controller;

use Symfony\Component\HttpKernel\Exception\FlattenException;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Bundle\TwigBundle\Controller\ExceptionController as BaseExceptionController;

/**
 * ExceptionController.
 */
class ExceptionController extends BaseExceptionController
{


    /**
     * Redirects 404s on urls with uppercase letters to the lowercase verion,
     * then uses it's parent class to
     * Convert an Exception to a Response.
     *
     * @param Request              $request   The request
     * @param FlattenException     $exception A FlattenException instance
     * @param DebugLoggerInterface $logger    A DebugLoggerInterface instance
     *
     * @return Response
     *
     * @throws \InvalidArgumentException When the exception template does not exist
     */
    public function showAction(Request $request, FlattenException $exception, DebugLoggerInterface $logger = null)
    {
        if ( (string) $exception->getStatusCode() === '404' && preg_match('/[A-Z]/', $request->getPathInfo())) {
            $lowercaseUrl = strtolower($request->getPathInfo());
            if ($request->isMethod('POST')) {
                return new RedirectResponse(
                    $lowercaseUrl,
                    '307'//307 status code preserves post information.
                );
            }
            $queryString = $request->getQueryString();
            return new RedirectResponse(
                $lowercaseUrl.( strlen($queryString)>0 ? '?'.$queryString : '' ),
                '301'//301 status code plays nice with search engines
                );
        }
        return parent::showAction($request, $exception, $logger);
    }
}

唯一的另一个技巧是您需要将此控制器配置为服务,您可以将正确的参数注入父类的构造函数:

在 services.yml

services:
    application.custom.exception_controller:
        class: Application\Symfony\TwigBundle\Controller\ExceptionController
        arguments: [ "@twig", "%kernel.debug%" ]

在 config.yml 中:

twig:
    exception_controller: application.custom.exception_controller:showAction

当然,您可以将这个控制器和服务定义粘贴到任何地方

于 2016-01-23T03:35:54.623 回答