Jim*_*mbo 5 php session symfony
我正在设置从Legacy代码库迁移到Symfony代码库的能力,并且我试图在两个应用程序之间共享旧的会话变量。
我目前可以var_dump($_SESSION)进入app_dev.php,并且user_id密钥来自旧版应用程序。但是,当我在控制器中运行以下命令时,没有任何会话变量:
var_dump($request->getSession()->all());
Run Code Online (Sandbox Code Playgroud)
为了明确起见,我目前可以访问$_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'];
Run Code Online (Sandbox Code Playgroud)
这显然是错误的方法,因为我也必须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']);
}
Run Code Online (Sandbox Code Playgroud)
吉姆的编辑
我创建了一个事件侦听器kernel.request- 每个传入的请求,我们都会循环遍历所有遗留会话变量$_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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如下面的评论所解释的,这不一定是最好的方法。但它有效。
| 归档时间: |
|
| 查看次数: |
1316 次 |
| 最近记录: |