doudu3961 2012-03-02 18:26
浏览 56
已采纳

PHP AWS SDK自动加载器与Codeigniter冲突

  • I'm using Codeigniter 2.1.0.
  • I'm including the Amazon Web Services SDK in a custom model using require_once APPPATH . "/libraries/aws_sdk/sdk.class.php";

This works well. However when CI decides it later needs to load it's db cache class, it calls (via CI_DB_driver::_cache_init):

if ( ! class_exists('CI_DB_Cache'))
{
    if ( ! @include(BASEPATH.'database/DB_cache.php'))
    {
        return $this->cache_off();
    }
}

This triggers the autoload of the AWS SDK (the exact method being CFLoader::autoloader).

I can get around this by telling class_exists not to autoload, as it seems that DB_cache.php is included anyway if class_exists returns false:

if ( ! class_exists('CI_DB_Cache', false))
{
    if ( ! @include(BASEPATH.'database/DB_cache.php'))
    {
        return $this->cache_off();
    }
}

This dirty fix works, but obviously only fixes the immediate problem. In general, what is the best way to ensure that CodeIgniter doesn't get confused with the autoload from other libraries?

Please note:

  • I've read bits and pieces about using spl_autoload_register. It seems that Codeigniter doesn't use this and I'm not sure how I should implement this safely. I would find a solid example of how and where I should implement this most useful (if, of course, this is the solution).
  • It appears that the AWS SDK already uses spl_autoload_register: spl_autoload_register(array('CFLoader', 'autoloader'));
  • 写回答

1条回答 默认 最新

  • dongxian8858 2013-01-11 17:11
    关注

    As you probably know, you don't really want to be modifying the core methods in CI. So, to prevent CI from conflicting with your class, you want to do something very similar to the following:

    Leave your folder structure as is, but create a new file outside your aws_sdk folder. Name it something like *Aws_loader* or something that makes sense to you. If you want to autoload the sdk, then in the CI autoloader file, add:

    CI Autoload file (application/config/autoload.php):

    $autoload['libraries'] = array('Aws_loader');
    

    Your init file:

    class CI_Aws_sdk{
        // for use with PHP < version 5
        /*public function CI_Aws_sdk(){
            require dirname(__FILE__) . DIRECTORY_SEPARATOR . "aws_sdk" .DIRECTORY_SEPARATOR . 'sdk.class.php';
        }*/
    
        // for use with PHP >= 5
        public function __construct(){
            require dirname(__FILE__) . DIRECTORY_SEPARATOR . "aws_sdk" .DIRECTORY_SEPARATOR . 'sdk.class.php';
        }
    }
    

    So your directory structure looks like this now:

    application --
      config --
      ...
      libraries --
        Aws_loader.php
        aws_sdk --
           sdk.class.php
    

    If you aren't autoloading the sdk, then in your controller, you can do this:

    $this->load->library('Aws_loader');
    

    Either way, CI with load the class for you and effectively separate any methods within it and now you can operate within that class just like any other library or model that you've loaded previously, without interfering with CI's methods, similar to this:

    $this->Aws_loader->do_something();
    

    You can use the same method for any third party class library or even one that you wrote yourself. A very similar arrangement can be used for models, libraries, helpers and the like. Hope this helps!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看