2
  • 我使用的是Codeigniter 2.1.0。
  • 我使用require_once APPPATH . "/libraries/aws_sdk/sdk.class.php";

这种运作良好,包括亚马逊Web服务SDK在一个自定义模式。然而,当CI以后决定它需要加载它的数据库缓存类,它调用(通过CI_DB_driver :: _ cache_init):PHP AWS SDK自动加载器与Codeigniter冲突

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

这触发了AWS SDK的自动加载(具体方法为CFLoader::autoloader)。

我能解决这个问题,告诉class_exists不会自动加载,因为它似乎DB_cache.php包含无论如何,如果class_exists返回false:

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

这个肮脏的修复工作,但显然只有解决眼前的问题。一般来说,确保CodeIgniter不会与其他库自动加载混淆的最佳方法是什么?

请注意:有关使用spl_autoload_register

  • 我读过的点点滴滴。似乎Codeigniter不使用这个,我不知道我应该如何安全地实现它。我会找到一个如何以及在哪里实施这个最有用的实例(当然,这是解决方案)。
  • 看来,AWS SDK已经使用spl_autoload_registerspl_autoload_register(array('CFLoader', 'autoloader'));

回答

4

正如你可能知道,你真的不希望被修改CI的核心方法。因此,防止CI从你的类发生冲突,你想要做的非常类似如下的内容:

留下你的文件夹结构原样,而是创建一个新的文件您aws_sdk文件夹。将它命名为* Aws_loader *或其他对您有意义的内容。如果要自动载入sdk,请在CI自动加载器文件中添加:

CI自动载入文件(application/config/autoload。PHP):

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

您的init文件:

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'; 
    } 
} 

所以,你的目录结构看起来像现在这样:

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

如果不自动加载该SDK,然后在你的控制器,你可以这样做:

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

无论哪种方式,CI为您加载类,并有效地分离其中的任何方法,现在您可以像在之前加载的任何其他库或模型一样在该类中操作,而不会干扰CI的方法,类似于以下内容:

$this->Aws_loader->do_something(); 

对任何第三方类库甚至是自己编写的类都可以使用相同的方法。一个非常类似的安排可以用于模型,图书馆,帮手等等。 希望这有助于!