Автозагрузчик PHP AWS SDK конфликтует с Codeigniter

  • Я использую Codeigniter 2.1.0.
  • Я включаю SDK Amazon Web Services в пользовательскую модель, используя require_once APPPATH . "/libraries/aws_sdk/sdk.class.php";

Это хорошо работает. Однако, когда CI решает, что позже ему нужно загрузить свой класс кеша db, он вызывает (через CI_DB_driver::_cache_init):

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_register: spl_autoload_register(array('CFLoader', 'autoloader'));

person Philip Bulley    schedule 02.03.2012    source источник


Ответы (1)


Как вы, наверное, знаете, на самом деле вам не нужно изменять основные методы в CI. Итак, чтобы предотвратить конфликт CI с вашим классом, вы хотите сделать что-то очень похожее на следующее:

Оставьте структуру папок без изменений, но создайте новый файл вне вашей папки aws_sdk. Назовите его, например, *Aws_loader* или как-то так, как вам удобно. Если вы хотите автозагрузить sdk, то в файле автозагрузчика CI добавьте:

Файл автозагрузки CI (application/config/autoload.php):

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

Ваш файл инициализации:

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();

Вы можете использовать тот же метод для любой сторонней библиотеки классов или даже для той, которую вы написали сами. Очень похожее расположение может быть использовано для моделей, библиотек, хелперов и т.п. Надеюсь это поможет!

person Ryan Conaway    schedule 11.01.2013