0

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

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

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

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

但是旧的类现在如何通过新的类版本执行请求的 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() 的情况下实现我想要的唯一方法吗?我不认为这是一个非常漂亮的方法,所以我正在寻找一种更清洁的方法来实现这一点。

4

1 回答 1

6

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

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

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

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

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

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

于 2016-08-09T14:09:32.323 回答