CodeIgniter - 版本化的库和模型

时间:2011-08-16 14:52:06

标签: php api codeigniter versioning

我使用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 个答案:

答案 0 :(得分:0)

当CI查找某个类时,它会按请求查找(加载<domain>/foo/bar然后再次<domain>/foo/bar 仍将重新加载Foo类,除非您有某种形式的缓存)并且当它感觉它具有适当的类时它终止(这是好的,因为如果它过于激进,它将导致冲突)。

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

答案 1 :(得分:0)

我知道这篇文章很旧,但是没有任何解决方案,但有一个解决方案。 (观察:我正在使用 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'] 等。