我试图处理别名(friendly-urls),可能我没做对。我想做的是转换网址,例如' / blog / my-post-about-something'进入' / posts / 23'。
我为kernel.request事件编写了一个监听器,它会进行一些操作并修改原始请求
class RequestListener
{
public function onKernelRequest(KernelEvent $event)
{
$request = $event->getRequest();
$converted_path = $this->getPathIfAny($request);
if ($converted_path) {
$request->server->set('REQUEST_URI', $converted_path);
}
}
public function getPathIfAny(Request $request)
{
return $somePathOrNull;
}
}
所有逻辑都正常工作并更新原始请求。问题是,即使我更改了' REQUEST_URI',属性$ pathInfo保持不变并指向上一个路径,因此我不断收到404错误。
有没有办法完全覆盖uri,或者我应该尝试以不同的方式解决问题?
这是监听器定义
my_cmf.request_listener:
class: My\CMFBundle\Event\RequestListener
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest , priority: -10}
答案 0 :(得分:4)
我的项目存在类似问题。我能够更新路径信息,但仍然努力将其传递给后续事件
试试这个:
$event->getRequest()->server->set('REQUEST_URI', '/en/guestbook');
$event->getRequest()->initialize($event->getRequest()->query->all(), $event->getRequest()->request->all(), $event->getRequest()->attributes->all(), $event->getRequest()->cookies->all(), $event->getRequest()->files->all(), $event->getRequest()->server->all(), $event->getRequest()->getContent());
var_dump($event->getRequest()->getPathInfo());
initialize方法重置整个类。
答案 1 :(得分:1)
稍微调查一下,我发现an issue on the Symfony2 github repository说明了这个问题。似乎它是Request类中一个引人注目的设计缺陷,将在Symfony 3中修复。*。到目前为止,我已经找到了一个临时解决方案。
通过扩展它并添加一个清除缓存数据的方法,可以处理Request类的缓存问题。
use Symfony\Component\HttpFoundation\Request as BaseRequest;
class Request extends BaseRequest
{
public function clearCache()
{
$this->requestUri = null;
$this->pathInfo = null;
$this->requestUri = null;
$this->baseUrl = null;
$this->basePath = null;
}
}
然后可以通过调用new方法从侦听器中绕过问题。
public function onKernelRequest(KernelEvent $event)
{
$request = $event->getRequest();
$converted_path = $this->getPathIfAny($request);
if ($converted_path) {
$request->clearCache();
$request->server->set('REQUEST_URI', $converted_path);
}
}
清除缓存可能会对应用程序的性能产生很小的影响,但我确信它不会引起注意,因为缓存只会被构建两次。
答案 2 :(得分:1)
您可以为内核发出子请求,但使用其他路径信息。
$url = 'Your url here...';
$subRequest = $request->duplicate(
null, // query
null, // request
null, // attributes
null, // cookies
null, // files
array_merge($request->server->all(), [
'REQUEST_URI' => $url,
])
);
return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
答案 3 :(得分:0)
事实上,这不是应该使用的行为。
真正的问题不是"我想将/ post / my-super-post转换为/ post / 1234",但是"我想在使用别名时获得好帖子&# 34。
首先,确保您的Post实体具有UNIQUE slug属性(其中包含" my-super-post"此处)。这些可以由STOF Doctrine Extension Bundle生成。
然后,在您的routing.yml上,使用类似:
的内容show_post:
path: /post/{slug}
defaults: { _controller: AcmeFooBundle:Bar:showPost }
并在您的控制器中:
public function showPostAction(Post $post) {
...
}
将自动包含您要查找的$post
。
您可以在此处找到有关slu的更多信息:http://symfony.com/doc/current/cookbook/doctrine/common_extensions.html 和ParamConverters:http://symfony.com/doc/2.0/bundles/SensioFrameworkExtraBundle/annotations/converters.html