Symfony2中是否有任何配置允许使用案例不敏感路由?
例如,下面的路线应该被视为相同:
www.exmaple.com/all
www.exmaple.com/ALL
有一个pull request about this,但没有参考如何实现它。
答案 0 :(得分:2)
我在纯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);
}
}
唯一的另一个技巧是你需要将这个控制器配置为一个服务,你可以将正确的参数注入到父类的构造函数中:
in 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
当然,您可以将此控制器和服务定义放在任何地方
答案 1 :(得分:1)
据我所知,Symfony 2无法做到这一点。但是,您应该可以使用Apache的mod_rewrite来完成它。有关详细信息,请参阅this blog post。
请务必阅读评论,因为初始帖子有一些错误。
答案 2 :(得分:1)
从Symfony2.4开始,您现在可以为路线定义条件并使用表达式语言进行复杂检查。请参阅Router: Completely Customized Route Matching with Conditions文档。
另一个解决方案是覆盖路由编译器类来更改/扩展路由匹配器的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在pull请求注释中所说,您可以覆盖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