我正在设置从Legacy代码库迁移到Symfony代码库的能力,并且我试图在两个应用程序之间共享旧的会话变量。
我目前可以var_dump($_SESSION)
进入app_dev.php
,并且user_id
密钥来自旧版应用程序。但是,当我在控制器中运行以下命令时,没有任何会话变量:
var_dump($request->getSession()->all());
为了明确起见,我目前可以访问$_SESSION['user_id']
,因此会话可以在应用程序之间成功共享,但是Symfony会话对象及其参数包不包含旧键。
我的目标:
user_id
密钥在$request->getSession()
通话中可用我的问题:
我已经尝试过PHP Session桥,但是我认为这不应该做我想要的事。添加bridge参数不仅在我的Symfony应用程序中没有任何作用,而且据我所读,这意味着将以某种方式在其他旧版应用程序中使用,而不是在Symfony中使用。
Symfony会话将诸如属性之类的数据存储在特殊的“包”中,该包使用$ _SESSION超全局变量中的密钥。这意味着Symfony会话无法访问旧应用程序可能设置的$ _SESSION中的任意键,尽管在保存会话时将保存所有$ _SESSION内容。[从与旧版会话集成]
我也看过TheodoEvolutionSessionBundle,但是它很旧,没有得到积极的支持或使用,也不适用于Symfony 3。
我已经注意到Symfony将其会话数据存储在下$_SESSION['_sf2_attributes']
,所以我最初的想法是在app_dev.php
:
$_SESSION['_sf2_attributes']['user_id'] = $_SESSION['user_id'];
这显然是错误的方法,因为我也必须session_start()
在那里打电话。
如何将旧$ _SESSION数据迁移到Symfony的Session对象中?Symfony是否有内置的东西可以帮助解决这个问题或可用的捆绑包?如果没有,我可以在哪里将自定义的$_SESSION['_sf2_attributes']
“ hack”放置在正确的位置以处理所有这些密钥的迁移?
Symfony在会话中引入了会话包的概念,因此所有内容均已命名。没有内置解决方案可以访问非命名间隔的会话属性。
解决方案是使用标量包,就像TheodoEvolutionSessionBundle一样。我不会直接使用它,而是实现一些对您的项目有用的自定义项(它们始终只为symfony1和codeigniter提供集成)。基于他们的想法,但可以使其适应您的需求。
另外,您可以实现一个kernel.request
侦听器,该侦听器会将旧的会话属性重写为Symfony的一个:
if (isset($_SESSION['user_id'])) {
$event->getRequest()->getSession()->set('user_id', $_SESSION['user_id']);
}
吉姆的编辑
我在上面创建了一个事件侦听器kernel.request
-每个传入的请求,我们都会遍历所有旧式会话var $_SESSION
,并将它们放入Symfony的会话包中。这是听众:
namespace AppBundle\Session;
use Symfony\Component\HttpFoundation\Session\Attribute\NamespacedAttributeBag,
Symfony\Component\EventDispatcher\EventSubscriberInterface,
Symfony\Component\HttpKernel\Event\GetResponseEvent,
Symfony\Component\HttpKernel\KernelEvents;
class LegacySessionHandler implements EventSubscriberInterface
{
/**
* @var string The name of the bag name containing all the brunel values
*/
const LEGACY_SESSION_BAG_NAME = 'old_app';
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
KernelEvents::REQUEST => 'onKernelRequest'
];
}
/**
* Transfer all the legacy session variables into a session bag, so $_SESSION['user_id'] will be accessible
* via $session->getBag('old_app')->get('user_id'). The first bag name is defined as the class constant above
*
* @param GetResponseEvent $event
*/
public function onKernelRequest(GetResponseEvent $event)
{
/** There might not be a session, in the case of the profiler / wdt (_profiler, _wdt) **/
if (!isset($_SESSION))
{
return;
}
$session = $event->getRequest()->getSession();
/** Only create the old_app bag if it doesn't already exist **/
try
{
$bag = $session->getBag(self::LEGACY_SESSION_BAG_NAME);
}
catch (\InvalidArgumentException $e)
{
$bag = new NamespacedAttributeBag(self::LEGACY_SESSION_BAG_NAME);
$bag->setName(self::LEGACY_SESSION_BAG_NAME);
$session->registerBag($bag);
}
foreach ($_SESSION as $key => $value)
{
/** Symfony prefixes default session vars with an underscore thankfully, so ignore these **/
if (substr($key, 0, 1) === '_' && $key !== self::LEGACY_SESSION_BAG_NAME)
{
continue;
}
$bag->set($key, $value);
}
}
}
如以下评论中所述,这不一定是最好的方法。但这有效。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句