Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在每个链接上保留查询字符串_Php_Symfony_Cookies - Fatal编程技术网

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

Php 在每个链接上保留查询字符串,php,symfony,cookies,Php,Symfony,Cookies,我想通过让用户在顶部navi的选择框中选择一个城市来个性化我的Symfony项目。为此,我得到了一个查询字符串,例如?city=berlin,我在控制器中获取该字符串并用其过滤结果 有没有一种简单的方法可以让每个url上的查询字符串保持活动状态,或者您更喜欢没有查询字符串的其他解决方案?也许是饼干 谢谢你的帮助 如果您需要根据路由路径(我建议您使用SEO URL而不是GET查询)将用户固定到某个条件,然后将其用作其他页面上某些行为的固定过滤器,那么您可以执行以下操作: BaseKernelEve

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

有没有一种简单的方法可以让每个url上的查询字符串保持活动状态,或者您更喜欢没有查询字符串的其他解决方案?也许是饼干


谢谢你的帮助

如果您需要根据路由路径(我建议您使用SEO URL而不是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;
    }
}
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);

        }
    }
}
内核事件:

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

        }
    }
}

因此,在所示的示例中,您将从会话中填充“city”,直到您访问将“city”更改为其他值的路由。

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

假设您在一个城市参数化页面上有一位访客。当有人复制url并与其他人共享时,除了你的页面外,你希望它是什么样子?城市不是任何个人状态,尽管您在上面提到了个性化(例如,有响应页面,我可以将字体设置为120%大小或设置更高的对比度,这将是一种个性化配置,我实际上不想在url中共享)

city是页面状态的一部分,而不是会话,因此我们希望city成为url的一部分。定义一个前缀路由,如
/{city}
,然后导入另一个带有该前缀的yml()

每次生成带有城市的url时,都必须对其进行设置。您可以手动执行此操作,也可以创建一些
cityCorrecatedRouter实现RouterInterface
获取
@router
@request\u堆栈
注入,并将
city
参数附加到
generate()
调用中的所有
参数
-数组中


@叶甫根尼库兹明的答案是,没有人期望有太多的魔法。当处理那些带有
城市
参数的路线时,最好在代码中阅读该参数,即路线的处理方式不同。当然,您还必须为twig定义一些新的
city\u路径
函数,它使用我们的
CityCoratedRouter

存储在会话中,对于您来说是一个不错的选择@IrfanAhmed这不是一个好主意。您不能与城市集共享URL(城市没有个性化设置,请参见下面的答案)2。谷歌机器人肯定不会将有状态会话内容添加到任何索引中,就像两个机器人以不同方式爬行您的站点,从相同的URL获取不同的内容一样。嘿,谢谢,我想这就是我想要做的……)但是如何使前缀成为可选的呢?我现在得到的是像/{city}/{category}/{id}这样的路线。我怎样才能使城市成为可选的,所以如果没有选择任何城市,所有城市的项目都会显示?我不知道路由器如何识别第一个前缀是{category}和它的{city},因为我的第一个想法是使用城市的GET querys。你可以使用
{category}/{id}
作为路线,并在
默认值中设置
城市