简体   繁体   English

Symfony遗留会话问题,缓慢地移植一个大型项目

[英]Symfony legacy session issues, porting a massive project slowly

Ok so we have this MASSIVE bare metal php project that we want to slowly convert over into Symfony3 好的,我们有这个MASSIVE裸机php项目,我们想慢慢转换成Symfony3

It's a constantly changing and updated project so we need this to be transparent, to make sure not to disrupt the people who are using it. 这是一个不断变化和更新的项目,所以我们需要透明,以确保不会破坏使用它的人。 They shouldn't notice a difference at all. 他们根本不应该注意到差异。

So the solution we decided to try was this: 所以我们决定尝试的解决方案是这样的:

  1. Stick the whole application into the /web 将整个应用程序粘贴到/ web中
  2. Keep the authenticator script in the legacy application (it's far too complex to port to the new one, and then update the old one to make use of the new session system) as all it's doing is setting a couple $_SESSION keys 将身份验证器脚本保留在遗留应用程序中(它太复杂,无法移植到新应用程序,然后更新旧脚本以使用新的会话系统),因为它所做的只是设置几个$ _SESSION键
  3. Nowhere else in the application is setting any session variables, just the authenticator. 应用程序中没有其他地方设置任何会话变量,只是验证器。

The problem is that the suffering through configuration of the Legacy Bridge , and a few choice stack overflow answers havent gotten us anywhere. 问题在于Legacy Bridge的配置带来的痛苦,以及一些选择 堆栈 溢出的答案并没有让我们处于任何地方。

  1. Using the Bridge 使用桥梁
    Configuring with the bridge as this doc says didn't affect anything except that the session it was reading from had nothing added to the $_SESSION['_sf2_attributes'] assoc or anywhere else for that matter. 如此doc所说的那样配置桥接器并没有影响任何东西,除了它正在读取的会话没有添加到$_SESSION['_sf2_attributes'] assoc或其他任何地方。

  2. Using the Bridge Component 使用Bridge组件
    As per this document that describes using the PhpBridgeSessionStorage component, when configured, would output along the lines of: 根据描述使用PhpBridgeSessionStorage组件的本文档 ,在配置时,将按以下方式输出:

ContextErrorException in classes.php line 83: Warning: ini_set(): A session is active. classes.php第83行中的ContextErrorException:警告:ini_set():会话处于活动状态。 You cannot change the session module's ini settings at this time 您目前无法更改会话模块的ini设置

When I combine it with the first method, it becomes exactly liek the first method. 当我将它与第一种方法结合起来时,它就变成了第一种方法。 It works, BUT I see absolutely NONE of the session data set in the legacy app, in my symfony controller 它工作正常,但我在我的symfony控制器中看到遗留应用程序中的会话数据集绝对没有

DefaultController.php on line 16:
array:3 [▼
  "_sf2_attributes" => & []
  "_sf2_flashes" => & []
  "_sf2_meta" => & array:3 [▼
    "u" => 1469839893
    "c" => 1469836213
    "l" => "0"
  ]
]
DefaultController.php on line 17:
Session {#2519 ▼
  #storage: PhpBridgeSessionStorage {#2520 ▼
    #bags: array:2 [▼
      "attributes" => AttributeBag {#2218 ▼
        -name: "attributes"
        -storageKey: "_sf2_attributes"
        #attributes: & []
      }
      "flashes" => FlashBag {#2219 ▼
        -name: "flashes"
        -flashes: & []
        -storageKey: "_sf2_flashes"
      }
    ]
    #started: true
    #closed: false
    #saveHandler: SessionHandlerProxy {#2522 ▼
      #handler: SessionHandler {#2217}
      #wrapper: true
      #saveHandlerName: "files"
    }
    #metadataBag: MetadataBag {#2521 ▼
      -name: "__metadata"
      -storageKey: "_sf2_meta"
      #meta: & array:3 [▼
        "u" => 1469839893
        "c" => 1469836213
        "l" => "0"
      ]
      -lastUsed: 1469839892
      -updateThreshold: "0"
    }
  }
  -flashName: "flashes"
  -attributeName: "attributes"
}
  1. Using a Listener 使用监听器
    One of the most popular "solutions" to this issue was this one from this SO answer 对于这个问题,最流行的“解决方案” 之一是来自这个SO答案

But when setup, and setup with a listener in app/config/services.yml like this: services: session.legacy: class: AppBundle\\Session\\LegacySessionHandler tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } 但是当在app/config/services.yml设置和设置监听器时,如下所示: services: session.legacy: class: AppBundle\\Session\\LegacySessionHandler tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

we get an error like this: 我们得到这样的错误:

LogicException in NativeSessionStorage.php line 240: Cannot register a bag when the session is already started. NativeSessionStorage.php第240行中的LogicException:在会话已启动时无法注册包。

I understand what this solution is trying to do, but it stuffers two problems from my side: 我理解这个解决方案正在尝试做什么,但它解决了我身边的两个问题:

I feel that by the time the kernel.request fires and my classes method is invoked, the event is supposed to still see actual real data set outside of the symfony context stored in the $_SESSION super global. 我觉得,当kernel.request触发并且我的类方法被调用时,该事件应该仍然可以看到存储在$_SESSION超全局中的symfony上下文之外的实际真实数据集。 As its supposed to kinda loop through the $_SESSION assoc and apply that data to a new bag. 因为它应该通过$ _SESSION assoc循环并将该数据应用到新的包。

1st problem is that there's nothing to set. 第一个问题是没有什么可设置的。 There is no key's set from the legacy app found in the session assoc that the listener has to work with 在侦听器必须使用的会话关联中找到的遗留应用程序中没有密钥集

2nd problem is that for some reason, i'm blocked from registereing a new bag... 第二个问题是,由于某种原因,我被阻止注册一个新的包......

  1. The "F-it" approach “F-it”方法

Because I could SEE keys like _sf2_attributes in the legacy app when I var_dump the $_SESSION super global, I decided hey why not just get the authenticator to dump it's keys into the _sf2_attributes key instead of the root! 因为当var_dump $_SESSION超全局时,我可以在遗留应用程序中看到像_sf2_attributes这样的键,我决定嘿,为什么不让验证者将它的密钥转储到_sf2_attributes键而不是根目录!

This didn't work either. 这也不起作用。 Like, at all. 就像,完全一样。 None of it shows up in my symfony controller. 没有一个出现在我的symfony控制器中。


I'm near my wits end here. 我靠近我的智慧结束了。 Is this a bug, is this by design? 这是一个错误,这是设计的吗?

I had this same problem and solved it by adding this in the config.yml: 我遇到了同样的问题并通过在config.yml中添加它来解决它:

session: 
        storage_id: session.storage.native
        handler_id: session.handler.native_file
        save_path: ~

To debug, I used the following PHP code in two places: 1) in a legacy script. 为了调试,我在两个地方使用了以下PHP代码:1)在遗留脚本中。 2) in a symfony controller. 2)在symfony控制器中。

$sessPath   = ini_get('session.save_path');
$sessCookie = ini_get('session.cookie_path');
$sessName   = ini_get('session.name');

echo '<br>sessPath: ' . $sessPath;
echo '<br>sessCookie: ' . $sessCookie;
echo '<br>sessName: ' . $sessName;

My issue was that the session.save_path was different for symfony vs. the legacy application. 我的问题是symfony与遗留应用程序的session.save_path不同。 Therefore, the symfony code could not access my legacy $_SESSION variables. 因此,symfony代码无法访问我的旧$ _SESSION变量。

Adding, the following line the config.yml fixed the problem: 添加,以下行config.yml修复了问题:

save_path: ~ save_path:〜

After I fixed this, the symfony controller code can see all of the $_SESSION variables directly: 修复此问题后,symfony控制器代码可以直接看到所有$ _SESSION变量:

echo "<pre>"; print_r($_SESSION); echo "</pre>";

No need for the "class LegacySessionHandler implements EventSubscriberInterface" solution, mentioned in the other stackoverflow question. 不需要在其他stackoverflow问题中提到的“类LegacySessionHandler实现EventSubscriberInterface”解决方案。 (part 3 of this question) (这个问题的第3部分)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM