我已经使用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
现在假设有一个1.0版本的调用,我加载了1.0版本的控制器,它加载了1.0版本的库和模型。在那之后,一个2.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
我希望不是……有更干净的方法吗?我觉得我遗漏了一些基本的东西。
谢谢你,史蒂夫。
当CI查找一个类时,它会逐个请求地查找(加载<domain>/foo/bar
然后<domain>/foo/bar
再次将仍然重新加载类Foo,除非您有某种形式的缓存),并且当它感觉它有适当的类时终止(这很好,因为如果它太积极,它会导致碰撞)。
假设您的CI版本知道它应该在哪个目录中查找,您应该不会有问题。当然,如果在同一个文件中有同一个类的两个版本,那么这在PHP中通常是行不通的。
我知道这个帖子很老了,但是,它没有任何解决方案,有一个解决方案。(奥林匹克广播服务公司。:我正在使用Codeigniter 3)
在config/autolload .php编码器文件中,您应该从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,
...
之后,你只需要将这个数组赋值给$ autolload ['model']:
$autoload['model'] = $versionedModelClasses;
就是这样。当你在1.0版本的控制器中调用OneModel时,模型1.0版本将被调用,当在2.0版本的控制器上,模型2.0版本将被调用。您不需要使用命名空间来使模型版本不同,因为codeigniter将只需要()您在$versionedModelClasses数组中的模型。您不需要重命名模型类名,因为我之前告诉过的在这里也适用。
同样的逻辑可以应用于库,等等,你只需要以同样的方式填充$ autolload ['libraries']等