Symfony2 解决方法,当设备禁用了 cookie


Symfony2 workaround when devices have cookies disabled

对于一个项目,我需要为访问者提供一个持久的会话。几年前,我遇到了Apple更新临时导致所有iPhone无法设置PHPSESSID cookie的问题。

我创建了一个回退方法,该方法检查 URL 中的 SESSION ID,并使用它来在请求之间保留会话。我知道这可以在 php 中启用.ini使用 session.use_trans_sid .

关键是我不希望这种情况总是发生。如果可能的话,我更喜欢饼干方法。在Symfony中是否有办法将此逻辑添加到添加会话标识符的路由方法中?

谁能帮我解释在哪里扩展 twig"path"方法以添加逻辑以选择性地将会话 ID 附加到该方法生成的所有 URL。

更新

让我发布有关我进度的最新信息,也许有人可以帮助我。我设法找到了如何通过替换参数中的generator_base_class来用我自己的代码扩展 UrlGenerator。

现在我有以下问题。我希望使用会话来执行一些逻辑。但是,我无法将这个核心组件作为服务访问。我已经尝试过为 UrlGenerator 和扩展路由器类提供编译器通行证,以便能够在其中一个类中进行依赖注入。

然而,直到现在,它可悲地失败了。在 UrlGenerator 类中获取会话组件的最佳部分是什么?

亏了这篇文章,我才能创建我的解决方案:覆盖路由器并将参数添加到特定路由(在使用路径/url之前)

最后,这就是我想出的代码。

In my service.xml
<parameters>
    <parameter key="router.class">Acme'CoreBundle'Component'Routing'Router</parameter>
    <parameter key="router.options.generator_base_class">Acme'CoreBundle'Component'Routing'Generator'UrlGenerator</parameter>
</parameters>

扩展Symfony的核心路由器以在ContainerAware中制作,并强制该容器到UrlGenerator。

namespace Acme'CoreBundle'Component'Routing;
use Symfony'Bundle'FrameworkBundle'Routing'Router as BaseRouter;
use Symfony'Component'DependencyInjection'ContainerAwareInterface;
use Symfony'Component'DependencyInjection'ContainerInterface;
use Symfony'Component'Routing'RequestContext;
class Router extends BaseRouter implements ContainerAwareInterface
{
    private $container;
    public function __construct(ContainerInterface $container, $resource, array $options = array(), RequestContext $context = null)
    {
        parent::__construct($container, $resource, $options, $context);
        $this->setContainer($container);
    }
    public function getGenerator()
    {
        $generator = parent::getGenerator();
        $generator->setContainer($this->container);
        return $generator;
    }
    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }
}

扩展 UrlGenerator 类。

namespace Acme'CoreBundle'Component'Routing'Generator;
use Symfony'Component'Routing'Generator'UrlGenerator as BaseUrlGenerator;
use Symfony'Component'HttpFoundation'Session'Session;
use Symfony'Component'DependencyInjection'ContainerAwareInterface;
use Symfony'Component'DependencyInjection'ContainerInterface;
/**
 * UrlGenerator generates URL based on a set of routes, this class extends the basics from Symfony.
 */
class UrlGenerator extends BaseUrlGenerator implements ContainerAwareInterface
{
    private $container;
    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }
    protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, array $requiredSchemes = array())
    {
        /** @var 'Symfony'Component'HttpFoundation'Session'Session $session */
        $session = $this->container->get('session');
        if (true !== $session->get('acceptCookies')) {
            $parameters[$session->getName()] = $session->getId();
        }
        return parent::doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes);
    }
}

最后,当会话值 acceptCookie 不等于 true 时,这会导致会话名称和 id 附加到生成的 URL。