在每个链接上保留查询字符串

时间:2015-04-17 15:18:54

标签: php symfony cookies

我想通过让用户在顶部导航栏中的选择框中选择一个城市来个性化我的Symfony项目。为此我得到了一个查询字符串,例如?city = berlin,我在我的控制器中获取并使用过滤结果。

是否有一种简单的方法可以将查询字符串保留在每个网址上,或者您更喜欢没有查询字符串的其他解决方案?也许用饼干?

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

如果您需要根据路径路径将用户粘贴到某些条件(我建议您使用SEO网址而不是GET查询),然后将其用作其他网页上某些行为的过滤器,那么您可以执行此类监听:

BaseKernelEvents:

namespace App\CoreBundle\Listener;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;

abstract class BaseKernelEvents
{
    /**
     * @var \Symfony\Bundle\FrameworkBundle\Routing\Router
     */
    private $router;

    /**
     * Initializes a new instance of the KernelEvents class.
     */
    public function __construct(ContainerInterface $container, Router $router)
    {   
        $this->container = $container;
        $this->router = $router;
    }

    /*
     * Store and get value by route param passed to uri to request and session
     */
    protected function storeParam(GetResponseEvent $event, $name, $default = 'none')
    {
        /* @var $request \Symfony\Component\HttpFoundation\Request */
        $request = $event->getRequest();

        /* @var $session \Symfony\Component\HttpFoundation\Session\Session */
        $session = $request->getSession();

        // instead of attributes you can get query from request here
        $value = $request->attributes->get($name);
        if (!$value) {
            $value = $session->get($name, $default);
        }

        return $this->setValues($event, $name, $value);
    }

    /*
     * Set name/value to request context and session
     */
    protected function setValues(GetResponseEvent $event, $name, $value)
    {
        /* @var $request \Symfony\Component\HttpFoundation\Request */
        $request = $event->getRequest();

        $context = $this->router->getContext();
        $session = $request->getSession();
        $session->set($name, $value);
        $context->setParameter($name, $value);

        return $value;
    }
}

KernelEvents:

namespace LaMelle\ContentSectionBundle\Listener;

use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;

use App\CoreBundle\Listener\BaseKernelEvents;

class KernelEvents extends BaseKernelEvents
{
    public function onKernelRequest(GetResponseEvent $event)
    {
        if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType())
        {
            $contentsectionSlug = $this->storeParam($event, 'city');

            // DO SOMETHINK BASE ON FILTER
            // LIKE CREATE GLOBAL TWIG VAR WITH FILTER VALUE 
            /* @var \Twig_Environment $globals */
            $globals = $this->container->get('twig');
            $globals->addGlobal('city', $contentsectionSlug);

        }
    }
}

因此,在示例中,您将拥有城市'从会话中填写,直到您将访问更改城市'到其他价值

答案 1 :(得分:0)

比谈论cookie更好的是关于有状态或无状态会话的问题。 Cookie只是将客户端映射到会话的实现。

假设您在一个城市参数化页面上有访问者。当有人复制网址并与其他人分享时,除了您的网页外,您有什么样的?城市任何个人状态,虽然您上面提到了个性化(例如,我可以将字体设置为120%大小或设置更高对比度的响应页面,将是个性化的配置我实际上不想分享网址。

city 是页面状态的一部分,而不是会话,因此我们希望city成为url的一部分。定义类似/{city}的前缀路由,并导入另一个带有该前缀的yml(http://symfony.com/doc/current/book/routing.html#prefixing-imported-routes)。

每次生成包含城市的网址时,都必须进行设置。您可以手动执行此操作或创建一些CityDecoratedRouter implements RouterInterface获取@router@request_stack,并将city参数附加到parameter中的所有generate() - 数组调用

@ EvgeniyKuzmin的答案是没有人期待的太多魔术。当处理那些具有city参数的路由时,最好在代码中读取它,以便区别对待路由。当然,您还必须为twig定义一些新的city_path函数,该函数使用我们的CityDecoratedRouter