我使用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
我希望不是......有更清洁的方法吗?我觉得我在这里缺少一些基本的东西。
谢谢你, 史蒂夫
答案 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'] 等。