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