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 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题