在Symfony 2请求中无法覆盖pathInfo



我正在尝试处理别名(友好的url),可能我做得不对。我想做的是将url转换为'/blog/my-post-about-something'到'/posts/23'。

我为内核编写了一个侦听器。进行一些操作并修改原始请求的请求事件

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: MyCMFBundleEventRequestListener
    tags:
      - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest , priority: -10}

此问题的相关链接:https://github.com/symfony/symfony/issues/10478

我的项目也有类似的问题。我能够更新路径信息,但仍然难以将其传递给后续事件

试试这个:

$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方法重置整个类

你可以为内核发出子请求,但是用另一个路径info.

    $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);

进一步调查后,我发现Symfony2 github存储库中存在一个问题。似乎这是Request类中一个值得注意的设计缺陷,将在Symfony 3.*中修复。到目前为止,我已经找到了一个临时的解决方案。

通过扩展Request类并添加一个清除缓存数据的方法来处理Request类的缓存问题。

use SymfonyComponentHttpFoundationRequest as BaseRequest;
class Request extends BaseRequest
{
    public function clearCache()
    {
        $this->requestUri = null;
        $this->pathInfo = null;
        $this->requestUri = null;
        $this->baseUrl = null;
        $this->basePath = null;
    }
}

则可以通过调用新方法从侦听器绕过该问题。

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);
    }
}

清除缓存可能会对应用程序的性能产生很小的影响,但我相信这不会很明显,因为缓存将只构建两次。

事实上,这不是应该使用的行为。

真正的问题不是"我想将/post/my-super-post转换为/post/1234",而是"我想在使用别名时获得好帖子"。

首先,确保你的Post实体有一个UNIQUE的属性(这里包含"my-super-post")。这些可以由STOF Doctrine扩展包生成。

然后,在你的路由。在Yml中,使用如下代码:

show_post:
    path: /post/{slug}
    defaults: { _controller: AcmeFooBundle:Bar:showPost }

在你的控制器中:

public function showPostAction(Post $post) {
...
}

将自动包含您正在查找的$post

你可以在这里找到更多关于鼻涕虫的信息:http://symfony.com/doc/current/cookbook/doctrine/common_extensions.html和参数转换器:http://symfony.com/doc/2.0/bundles/SensioFrameworkExtraBundle/annotations/converters.html

相关内容

  • 没有找到相关文章

最新更新