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

时间:2016-07-30 01:00:46

标签: php session symfony

好的,我们有这个MASSIVE裸机php项目,我们想慢慢转换成Symfony3

这是一个不断变化和更新的项目,因此我们需要透明,以确保不会破坏使用它的人。他们根本不应该注意到差异。

所以我们决定尝试的解决方案是:

  1. 将整个应用程序粘贴到/ web
  2. 将身份验证器脚本保留在旧应用程序中(它太复杂了,无法移植到新应用程序,然后更新旧脚本以使用新的会话系统)就像它所做的一样正在设置几个$ _SESSION键
  3. 应用程序中的任何其他地方都没有设置任何会话变量,只是验证器。
  4. 问题在于,通过配置Legacy Bridge以及一些choice stack overflow答案所带来的痛苦并没有让我们处于任何地方。

    1. 使用网桥
      使用the bridge as this doc says进行配置并不会影响任何内容,除了它正在阅读的会话没有添加到$_SESSION['_sf2_attributes'] assoc或其他任何地方。

    2. 使用Bridge Component
      根据描述使用PhpBridgeSessionStorage组件的this document,在配置时,将按以下行输出:

    3.   

      classes.php第83行中的ContextErrorException:   警告:ini_set():会话处于活动状态。您目前无法更改会话模块的ini设置

      当我将它与第一种方法结合使用时,它就变成了第一种方法。它工作正常,但我在我的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. 使用监听器
        最受欢迎的解决方案之一"这个问题是this one from this SO answer
      2. 但是在设置时,使用app/config/services.yml中的监听器进行设置,如下所示: services: session.legacy: class: AppBundle\Session\LegacySessionHandler tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

        我们收到如下错误:

          

        NativeSessionStorage.php第240行中的LogicException:无法注册a   会议已经开始时包。

        我理解这个解决方案正在尝试做什么,但它解决了我身边的两个问题:

        我觉得在调用kernel.request fires和my classes方法时,事件应该仍然可以看到存储在$_SESSION超级全局中的symfony上下文之外的实际真实数据集。因为它应该通过$ _SESSION assoc循环并将该数据应用到新的包。

        第一个问题是没有什么可设置的。在侦听器必须使用的会话关联中的遗留应用程序中没有设置关键字

        第二个问题是,出于某种原因,我被阻止注册一个新的包...

        1. " F-it"方法
        2. 因为当我_sf2_attributes var_dump超级全局时,我可以在遗留应用中找到$_SESSION之类的密钥,所以我决定嘿嘿,为什么不让这个身份验证器转储它呢?键入_sf2_attributes键而不是根!

          这也没有用。就像,完全一样。没有一个出现在我的symfony控制器中。

          我靠近我的智慧结束了。这是一个错误,这是设计的吗?

1 个答案:

答案 0 :(得分:2)

我有同样的问题并通过在config.yml中添加它来解决它:

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

要进行调试,我在两个地方使用了以下PHP代码:1)在旧脚本中。 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;

我的问题是symfony与遗留应用程序的session.save_path不同。因此,symfony代码无法访问我的旧$ _SESSION变量。

添加,以下行config.yml修复了问题:

  

save_path:〜

修复此问题后,symfony控制器代码可以直接看到所有$ _SESSION变量:

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

不需要在其他stackoverflow问题中提到的“类LegacySessionHandler实现EventSubscriberInterface”解决方案。 (这个问题的第3部分)