【问题标题】:Live self-updating PHP class实时自更新 PHP 类
【发布时间】:2016-08-09 13:59:23
【问题描述】:

我有一个 PHP 类,它可以与我们正在开发的 API 进行通信。我不想使用不同的 API 版本并让用户手动更新 PHP 类脚本,我想让这个过程自动化。

当发现更新时,此更新必须即时完成。这是我的想法:

  • 用户的程序尝试通过我们提供的 PHP 类访问 API
  • PHP 类检查更新
  • 如果有更新,该类将下载新版本的类,并希望新版本的类处理 API 请求。

这显然意味着PHP类需要对该类所在文件的写权限,所以它可以简单地用新版本覆盖该类。

但是 old 类现在如何通过新的类版本执行请求的 API 请求呢?在一个完美的世界里,我正在寻找一种不使用 eval() 的方法,因为这个函数在许多主机上被阻止。

详细说明:

$myApi = new MyApi;
$myApi->registerCustomer($customerData);

registerCustomer() 函数会做这样的事情:

if (classNotUpToDate) {
    downloadNewClass();
    registerCustomerthroughNewClass()
} else {
    registerCustomerDo();
}

现在我能想到的唯一方法是:

  • 将新的类版本下载到变量中
  • 在该变量中,将 class MyApi {... 替换为 class MyApiUpdate {..
  • 再次包含当前文件,加载新的更新类
  • 创建新类的实例:$myApiUpdate = new MyApiUpdate;
  • 调用registerCustomer()函数:$myApiUpdate->registerCustomer($customerData);
  • 用新的类代码覆盖当前文件内容(不替换)

这是在不创建新文件或使用 eval() 的情况下实现我想要的唯一方法吗?我不认为这是一个非常漂亮的方法,所以我正在寻找一种更清洁的方法来实现这一点。

【问题讨论】:

  • 与其有一个自我更新的类,也许你可以有一个更新管理器来调解这个过程,因为一旦一个类被加载,你是否修改文件都没有关系,在下一个请求之前或除非您使用另一个框架,否则它无法重新加载。
  • 重写一个核心程序结构(例如一个类)来促进协议更新过程是不好的。为什么?因为你可能会遇到数百万个问题。然而,既然你已经在这里了——你用过composer吗?
  • 遗憾的是,我们仅限于 1 文件库。所以我们不能有多个文件,也不能使用 Composer 之类的任何库。
  • 我们是在谈论 CLI 还是 web?
  • 我们在谈论网络。

标签: php class updates automatic-updates


【解决方案1】:

我认为这种方法相当非常不安全,因此不推荐。

相反,我建议您的 API 应该要求每个请求都发送一个“API 版本”指示符:客户端通知服务器它正在使用的 API 版本,并且服务器以类似的方式通知客户端响应的版本给它。

使版本尽可能“向上兼容”。较新版本的 API 可以与较旧版本通信,并且由于双方可以自我识别,因此您可以确切地知道每个人可以使用和不能使用的请求。如果您发明了一个取代旧 API 调用的新 API 调用,请将它们 both 留在实现中,即使您“存根”其中一个或让旧调用的实现调用代码较新的。

如果必要和适当,可以使用子类来实现不同版本的 API。

当然,您应该为每个 API 版本提供测试套件,并且您应该验证所有旧测试是否继续针对新版本正确运行。也就是说,没有“回归”。

但是,不,no“自动即时更新”和no可写文件。正如他们所说:“不仅是‘不’,而是‘见鬼,不!’”

【讨论】:

  • 感谢您的回答。这当然是正确的做事方式。可悲的是,在我的项目中,这根本不可能。问题是它不仅仅是一个 API。它是一个完整的集成系统,带有控制面板、后端和不断变化的复杂算法。我们不能任何过时的API请求。
  • 嗯……“以前的版本”并不一定意味着“过时”。如果双方相互交流他们使用的是什么版本,并且双方都验证了彼此是否兼容,那么它应该可以工作。
  • 如果使用它的软件需要新功能,而以前版本的 API 中不存在,则该类已过时。
  • 如果您需要“实时更新”,那么我建议创建一个初始握手呼叫,可以说,在其中双方交换他们的电话卡。服务器可能会回复,“我有一个更新给你。” (所有其他 API 调用将拒绝与旧版本对话。)客户端现在必须发出“请发送给我”请求。主机回复一个 加密签名 文件,客户端验证并安装该文件。 (理想情况下,它会调用一些特权命令,该命令在可以修改正常只读文件的用户 ID 下运行。
  • 另外请注意,通过将其放入“初始握手”中,客户端可以更新 PHP,而之前从未require()d 它。 ### 是的,通过交换版本号,双方可以立即认识到存在不兼容。他们将拒绝相互交谈(“初始握手”和版本更新序列除外。)
猜你喜欢
  • 1970-01-01
  • 2012-01-12
  • 2018-03-18
  • 1970-01-01
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
  • 2020-07-23
  • 2015-03-25
相关资源
最近更新 更多