我的任务是找到在silex框架中包装定制应用程序的解决方案,因为他们将继续使用silex。问题是遗留应用程序是扁平的php风格,没有控制器或模型,php在via文件中嵌入了mysql查询。
我一直在努力寻找任何干净的解决方案来包装遗留的应用程序在silex的路由,以允许新的部分在基于控制器的setp而不是平面php中完成。我一直在检查堆栈溢出和其他谷歌结果之间的一段时间,但他们似乎最终指定了使用基于控制器设置的遗留应用程序执行默认路由的方法。
为了更好地衡量,遗留应用程序确实使用会话变量,所以解决方案必须允许使用这些。
感谢所有的帮助。
在人们问之前,我已经看过了Silex/Symfony中的路由-提供默认路由,它类似于我想要做的,但我需要使它与平面php应用程序一起工作,而不是传统的控制器。
解决方案最终分为两部分。
- 将遗留代码放在silex应用程序的web根目录中。
- 获取silex应用程序来存储silex和遗留应用程序都可以访问的会话。
代码放置
通过将遗留代码放入web文件夹,URL中的任何匹配文件的内容都将转到该文件,而不是寻找路由。这允许不需要为所有旧代码创建路由,因为在我们的情况下,它不是基于控制器的,需要与本网站提到的大多数其他重构不同的处理方式。
将代码放入web目录也意味着我们可以继续对旧代码进行更新和更改,同时在可用的时间内编写新的基于Silex的代码来替换它。
当涉及到使用相同的会话时,我们选择....虽然不太理想,但它允许我们继续执行我们的计划,而不会妨碍任何应用程序的使用。当前的计划是,一旦我们完成了将应用程序的代码迁移到Silex,就实现数据库存储会话。
我们选择了Symfony session avoid _sf2_attributes。这是一个相当难看的解决方案,但它提供了我们在尝试以最小的工作量及时迁移应用程序时所需的灵活性。我们的目标是将它完全迁移到新的Silex应用程序,但是完成这个任务需要一年以上的时间。
下面是在我们的Silex应用程序中如何配置会话的。它正在使用基于文件的存储$app->register(new SilexProviderSessionServiceProvider(), array(
'cookie_lifetime' => 86400,
));
$app['session.storage'] = $app->share(function () use ($app) {
return new SymfonyComponentHttpFoundationSessionStorageLegacySessionStorage;
});
这里是最初位于这里的控制器代码的副本,以防它在某个时候被删除。
<?php
use SymfonyComponentHttpFoundationSessionStorageNativeSessionStorage;
/**
* Session sotrage that avoids using _sf2_attributes subkey
* in the $_SESSION superglobal but instead it uses
* the root variable.
*/
class LegacySessionStorage extends NativeSessionStorage
{
const SYMFONY_SESSION_SUBKEY = '_sf2_attributes';
/**
* @inheritdoc
*/
protected function loadSession(array &$session = null)
{
if (null === $session) {
$session = &$_SESSION;
}
parent::loadSession($session);
foreach ($this->bags as $bag) {
$key = $bag->getStorageKey();
if (self::SYMFONY_SESSION_SUBKEY === $key)
{
$bag->initialize($session);
}
}
}
}
我希望这能帮助其他人从他们的眼中钉迁移到新的编码风格。我想确保随着时间的推移总结我们的发现,以确保其他人在未来不需要看那么多。
Matthias Noback写了一篇非常好的文章。基本上,诀窍是匹配遗留url并在Silex Response对象中返回遗留输出。注意使用ob_*方法使用内存
另一种选择是就地现代化扁平PHP应用程序(使您拥有一个统一的代码库),而不是包装它(使您拥有2个代码库)。详细步骤见现代化PHP中的遗留应用程序,但概述如下:
- 实现自动装弹器
- 将类和函数整合到中心位置
- 删除全局变量以支持依赖注入
- 删除new关键字以支持依赖注入
- 写单元测试
- 提取SQL代码到网关类("Model, Part 1")
- 将域逻辑提取到事务类("模型,第2部分")
- 提取表示逻辑到响应类("View")
- 提取动作逻辑到控制器类("Controller")
- 提取剩余包括
- 从文档根目录 提取应用程序代码
- 实现前端控制器
- 为依赖注入容器准备应用程序 添加依赖注入容器
希望对你有帮助。