【问题标题】:CodeIgniter - Versioned Libraries and ModelsCodeIgniter - 版本库和模型
【发布时间】:2011-08-16 14:52:06
【问题描述】:

我已经使用 CodeIgniter 构建了一个 Web API,并且即将推出更新版本。因此,假设您可以对其进行以下调用:

mysite.com/api/v1.0/get_customers
mysite.com/api/v2.0/get_customers

(假设我正在使用路由来获取正确的控制器版本)。

我有一个这样的 CI 库结构:

controllers/
   + 1.0/
      + Api.php
   + 2.0/
      + Api.php
libraries/
   + 1.0/
      + Customer.php
   + 2.0/
      + Customer.php
models/
   + 1.0/
      + Customer_model.php
   + 2.0/
      + Customer_model.php

现在假设有一个 v1.0 调用进来,我加载了 1.0 控制器,它加载了 1.0 库和模型。之后,一个 v2.0 调用进来,我加载了所有 2.0 版本...

CI 是否会识别到 1.0 类的路径与 2.0 类不同并重新加载它们(而不是认为它们已经加载,因为它们共享相同的类名,而实际上它是 1.0 版本)?

人们如何处理这个问题?我是否需要使用不同的类名,像这样:

class Customer_1_0
class Customer_2_0
class Customer_model_1_0
class Customer_model_2_0

我希望不是...有没有更清洁的方法来做到这一点?我觉得我在这里缺少一些基本的东西。

谢谢, 史蒂夫

【问题讨论】:

  • 我不明白。您正在谈论 2 个单独的 HTTP 请求。那么为什么 Codeigniter 会“认为他们已经加载了”?
  • API1 目前已经存在,还是正在考虑为未来设计结构?

标签: php api codeigniter versioning


【解决方案1】:

当 CI 查找一个类时,它会逐个请求地查找(加载 <domain>/foo/bar 然后 <domain>/foo/bar 再次 仍然会重新加载类 Foo,除非你有一些缓存form) 并且当它认为它具有适当的类时终止(这很好,因为如果它过于激进,它会导致冲突)。

假设您给定的 CI 版本知道它应该在哪个目录中查找,那么您应该没有问题。当然,如果您在同一个文件中有同一个类的两个版本,那么一般来说这在 PHP 中是行不通的。

【讨论】:

  • 所以,即使两个库都被称为“客户”,如果我这样做 $this->load->library("1.0/customer") 然后 $this->load->library(" 2.0/customer") 之后,CI 不会假设已经加载的版本 (1.0) 可重复用于 2.0 调用?我在日志中看到一堆让我担心的问题:“DEBUG - 2011-08-f16 14:21:10 --> Customer 类已经加载。第二次尝试被忽略。”
  • 有点。如果你在同一个请求中调用两者(一个控制器方法),那么就会发生类型冲突,CI 将忽略第二个调用。这意味着先叫什么,谁就赢。至于调试线,这没什么好担心的。有时图书馆需要图书馆。
【解决方案2】:

我知道帖子很旧,但是没有任何解决方案,但有解决方案。 (观察:我正在使用 Codeigniter 3)

在 config/autoload.php codeigniter 文件中,您应该获得从 URI 请求的 API 版本。像这样的:

$URISegments = explode('/', $_SERVER['REQUEST_URI']);

$version = $URISegments[2]; // get the version from the correct segment

检查请求的版本是否是有效的 API 版本:

$APIPath = APPPATH . 'controllers' . DIRECTORY_SEPARATOR . $version;

if ( ! file_exists($APIPath)) {
  // give some error and exit
}

现在我们知道我们有一个有效的 API 版本被请求,所以,我们应该做的是生成 API 将使用的模型版本的正确路径:

$unversionedModelClasses = ['OneModel', ...];

$versionedModelClasses = array_map(
  function($modelClass) use ($version)
  {
    return $version . '/' . $modelClass;
  }
, $unversionedModelClasses);

结果是这样的数组:

Array
(
[0] => v1.0/OneModel,
...

之后,您只需将此数组分配给 $autoload['model']:

$autoload['model'] = $versionedModelClasses;

就是这样。当您在控制器版本 1.0 中调用 OneModel 时,将调用模型版本 1.0,在 2.0 控制器上时,将调用模型版本 2.0。 您不需要使用命名空间来使模型版本不同,因为 codeigniter 只会 require() 您在 $versionedModelClasses 数组上拥有的模型。 您不需要重命名模型类名称,因为我之前告诉过的同样适用于此。

同样的逻辑可以应用于库,等等,你只需要以同样的方式填充 $autoload['libraries'] 等。

【讨论】:

    猜你喜欢
    • 2020-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多