5

在“本机”Zend Framework 应用程序中,我将通过将 ezComponents 的自动加载器添加到 Zends 自动加载器来启用 ezComponents:

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

现在,我想知道如何对 Magento 做同样的事情。有没有办法扩展 Varien_Autoload(magentos 自动加载器)以实现 ezComponents 的轻松集成?或者:除了 Magento 的自动加载器之外,有没有一种方法可以在不相互干扰的情况下使用 Zends 自动加载器?

编辑:

好吧,我通过将以下内容添加到 Varien_Autoload 中的函数 autoload() 来实现了一种解决方法:

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

    }

不过,我认为这是一个非常糟糕的 hack,因为它会在升级 Magento 时被覆盖。有人有更好的主意吗?

4

3 回答 3

17

我在这里的基本方法是创建一个带有观察者的自定义模块

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由于命名空间中的类的加载通常由我们将要删除的自动加载器处理,因此我们需要做一些额外的 jiggery-pokery 。更多细节见评论

//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');
于 2011-01-08T23:02:22.470 回答
0

我刚刚将 Sailthru_Client 类集成到 Magento 中,认为这可能会有所帮助。

我有sailthru.phpSailthru 客户端 API,其中包含Sailthru_Client类。

我创建了magentoroot/lib/Sailthru文件夹,然后将sailthru.php 复制到其中,然后重命名为 makeClient.phpmagentoroot/lib/Sailthru/Client.php。此模式由Varien_Autoload类自动加载。

于 2010-11-04T13:59:31.747 回答
0

我快速浏览了 Varien 的自动加载器的代码,它似乎使用了对spl_autoload_register的调用,这是一个用于执行自动加载的堆栈。虽然我认为添加到默认的 Magento 自动加载器不会有太大的成功,但这意味着您应该能够在 Magento 的顶部推送另一个自动加载器。

希望有帮助!

谢谢,乔

于 2010-11-03T13:33:32.653 回答