Как интегрировать ezComponents с magento

в «родном» приложении Zend Framework я бы разрешил использование ezComponents, добавив автозагрузчик ezComponents в автозагрузчик Zends:

$autoLoader = Zend_Loader_Autoloader::getInstance();
require_once('../library/EZComponents/Base/src/base.php');
$autoLoader->pushAutoloader(array('ezcBase', 'autoload'), 'ezc'); 

Теперь мне интересно, как я мог бы сделать то же самое с Magento. Есть ли способ расширить Varien_Autoload (автозагрузчик magentos), чтобы упростить интеграцию ezComponents? ИЛИ: Есть ли способ использовать автозагрузчик Zends помимо автозагрузчика из Magento, не мешая друг другу?

редактировать:

Что ж, я реализовал обходной путь, добавив следующее в функцию autoload() в Varien_Autoload:

if(substr($class, 0, 3) == 'ezc'){
        require_once('EZComponents/Base/src/base.php');
        return ezcBase::autoload($class);

    }

Я считаю это очень плохим взломом, потому что он будет перезаписан при обновлении Magento. У кого-нибудь есть идея получше?


person volka    schedule 03.11.2010    source источник
comment
Ну, я реализовал обходной путь, добавив следующее в функцию autoload() в Varien_Autoload: [code] if(substr($class, 0, 3) == 'ezc'){ require_once('EZComponents/Base/src/base .php'); вернуть ezcBase::autoload($class); } [/code] Я считаю это очень плохим взломом, потому что он будет перезаписан при обновлении Magento. У кого-нибудь есть идея получше?   -  person volka    schedule 03.11.2010


Ответы (3)


Мой основной подход здесь заключался бы в создании пользовательского модуля с наблюдателем для

controller_front_init_before

событие. В наблюдателе событий вы сможете настроить автозагрузчик по своему усмотрению. На Magento Wiki есть статья о настройке наблюдателей за событиями. Событие controller_front_init_before — одно из первых неуниверсальных событий, которые возникают в Magento. Вот почему мы его используем.

Большая проблема, которую нам нужно решить, заключается в следующем: автозагрузчик Magento находится в стеке первым, и если он не найдет файл (что будет в случае с классами EZComponent), его включение вызовет ошибку, которая остановит выполнение.

Итак, что нам нужно сделать в нашем наблюдателе событий выше, это

  1. Удалите Varien_Autoloader из spl_autoload stack

  2. Зарегистрируйте наш собственный автозагрузчик (мы будем использовать Zend_Autoloader, так как он поставляется с Magento, и вы, кажется, знакомы с ним)

  3. Повторно добавьте Varien_Autoloader в стек

Нам придется немного повозиться, так как загрузка классов в пространстве имен Zend обычно обрабатывается автозагрузчиком, который мы будем удалять. Смотрите комментарии для более подробной информации

//we need to manually include Zend_Loader, or else our zend autoloader
//will try to use it, won't find it, and then try to use Zend_Loader to
//load Zend_Loader
require_once('lib/Zend/Loader.php');


//instantiate a zend autoloader first, since we 
//won't be able to do it in an unautoloader universe
$autoLoader = Zend_Loader_Autoloader::getInstance();        

//get a list of call the registered autoloader callbacks
//and pull out the Varien_Autoload.  It's unlikely there
//are others, but famous last words and all that
$autoloader_callbacks = spl_autoload_functions();
$original_autoload=null;
foreach($autoloader_callbacks as $callback)
{
    if(is_array($callback) && $callback[0] instanceof Varien_Autoload)
    {
        $original_autoload = $callback;
    }
}

//remove the Varien_Autoloader from the stack
spl_autoload_unregister($original_autoload);

//register our autoloader, which gets on the stack first
require_once('library/EZComponents/Base/src/base.php');
$autoLoader->pushAutoloader(array('ezcBase', 'autoload'), 'ezc');           

//lets just make sure we can instantiate an EZ class
#$test = new ezcBaseFile();
#var_dump(get_class($test));

//IMPORANT: add the Varien_Autoloader back to the stack
spl_autoload_register($original_autoload);      

Поместите приведенный выше код в метод наблюдателя, и все будет хорошо.

Другой подход, который вы могли бы использовать, который больше соответствовал бы шаблонам Magento, заключался бы в создании пользовательского модуля, реализующего загрузчик EZComponent.

$o = Mypackage_Mymodule_Loader::getModel('ezcBaseFile');

Затем вы должны реализовать стиль автозагрузчика, требующий кода в вашем статическом методе getModel, и использовать его всякий раз, когда вам нужен класс ezcBaseFile. Вам, вероятно, понадобятся методы для загрузки класса без создания экземпляра объекта, если вы хотите вызвать статический метод для ezcBaseFile базового класса.

$o = Mypackage_Mymodule_Loader::getLoadclass('ezcBaseFile');
person Alan Storm    schedule 08.01.2011
comment
Большое спасибо @alan-storm. Это очень помогло мне при попытке настроить DomPdf. Я не уверен, что полностью понимаю, как сделать второй вариант. - person dan.codes; 26.04.2012
comment
@dan.codes Я написал это больше года назад — в эти дни я бы просто придерживался варианта 1. Вариант 2 заключался в том, что я очень хотел, чтобы весь мой код выглядел как фаза кода Magento. - person Alan Storm; 26.04.2012
comment
Начиная с PHP 5.3 вам не нужно делать ложные манипуляции, чтобы сначала получить автозагрузчик. Третий параметр — это флаг для добавления вашего автозагрузчика в начало, а не в конец. - person Lee Saferite; 15.10.2014

Я быстро взглянул на код автозагрузчика Varien, и оказалось, что он использует вызов spl_autoload_register, который стек для выполнения автозагрузок. Хотя я не думаю, что вам удастся добавить автозагрузчик Magento по умолчанию, это означает, что вы сможете добавить другой автозагрузчик поверх Magento.

Надеюсь, это поможет!

Спасибо, Джо

person Joseph Mastey    schedule 03.11.2010
comment
Привет, Джозеф, да, спасибо. Я пробовал это, но это не сработало. Может быть, я сделал это неправильно. Я покопаюсь в этом во второй раз и попробую еще раз. - person volka; 04.11.2010
comment
Это звучит как хорошая идея, но когда автозагрузка Magento не может загрузить класс, она выдает предупреждение, которое останавливает выполнение. Поскольку автозагрузка Magento находится в стеке первой, это означает, что она никогда не попадет в другие автозагрузчики. Больше информации в моем ответе. - person Alan Storm; 09.01.2011

Я только что интегрировал класс Sailthru_Client в Magento, подумал, что это может помочь.

У меня есть sailthru.php, клиентский API Sailthru, который содержит класс Sailthru_Client.

Я создал папку magentoroot/lib/Sailthru, затем скопировал в нее Saithru.php, затем переименовал ее в Client.php, сделав ее magentoroot/lib/Sailthru/Client.php. Этот шаблон автоматически загружается классом Varien_Autoload.

person Carmelo Capinpin    schedule 04.11.2010
comment
Я думаю, что это не будет работать с ezComponents (или, лучше сказать, не стоит усилий), так как тогда мне нужно будет переименовать сотни классов. И тогда обновление ezComponents будет беспорядочным. - person volka; 04.11.2010
comment
Я думаю, что это не будет работать с ezComponents (или, лучше сказать, не стоит усилий), так как тогда мне нужно будет переименовать сотни классов. И тогда обновление ezComponents будет беспорядочным. - person volka; 05.11.2010