简体   繁体   中英

CodeIgniter - Versioned Libraries and Models

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM