CodeIgniter - 版本化的库和模型

发布于 2024-11-29 17:27:56 字数 852 浏览 0 评论 0原文

我已经使用 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

我希望不需要......有没有更干净的方法来做到这一点?我觉得我在这里错过了一些基本的东西。

谢谢你, 史蒂夫

I've built a web API using CodeIgniter and am about to roll out an updated version. So, let's say you can make the following calls into it:

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

(Assume I'm using routes to get to the right controller version).

I have a CI library structure like this:

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

Now assume a v1.0 call comes in and I load the 1.0 controller, which loads the 1.0 library and model. After that, a v2.0 call comes in and I load all 2.0 versions...

Will CI recognize that the path to the 1.0 classes are different than the 2.0 classes and re-load them (rather than thinking they already loaded because they share the same class name when in fact it's the 1.0 version)?

How do people deal with this? Do I need to use different class names, like this:

class Customer_1_0
class Customer_2_0
class Customer_model_1_0
class Customer_model_2_0

I hope not... Is there a cleaner way to do this? I feel like I am missing something fundamental here.

Thank you,
Steve

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

故人的歌 2024-12-06 17:27:56

当 CI 查找类时,它会逐个请求地查找(加载 /foo/bar 然后加载 /foo/bar 再次仍然会重新加载类 Foo,除非你有某种形式的缓存)并且当它感觉它具有适当的类时它会终止(这很好,因为如果它太激进,它会导致碰撞)。

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

When CI looks for a class, it looks on a request-by-request basis (loading <domain>/foo/bar then <domain>/foo/bar again will still reload the class Foo, unless you have caching of some form) and it terminates when it feels that it has the appropriate classes (which is good, because if it were too aggressive, it would cause collisions).

Assuming that your given CI version knows which directory it is supposed to look in, you should not have a problem. Of course, if you have two versions of the same class in the same file, that wouldn't work in PHP in general.

妞丶爷亲个 2024-12-06 17:27:56

我知道这篇文章很旧,但是没有任何解决方案,并且有一个解决方案。
(观察:我正在使用 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 时,将调用模型版本 2.0。
您不需要使用命名空间来使模型版本不同,因为 codeigniter 只会 require() $versionedModelClasses 数组上的模型。
您不需要重命名模型类名称,因为我之前所说的同样也适用于此处。

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

I know the post is very old but, it was left without any solution and there is a solution to that.
(Obs.: i am using Codeigniter 3)

In config/autoload.php codeigniter file you should get the API version requested from URI. Something like this:

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

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

Check if the version requested is a valid API version:

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

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

Now we know we have a valid API version being requested, so, what we should do is generate the correct path to the model version the API will consume:

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

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

The result of that is an array like this:

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

After that, you just have to assign this array to $autoload['model']:

$autoload['model'] = $versionedModelClasses;

And that is it. When you call OneModel in your controller version 1.0, the model version 1.0 will be called, when on 2.0 controller, model version 2.0 will be called.
You don't need use namespace to make the models versions diferents because codeigniter will only require() the models you have on $versionedModelClasses array.
You don't need to rename the model class names, since the same i told previously apply here too.

The same logic can be applied to libraries, and so on, you just need to populate the $autoload['libraries'] etc the same way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文