【问题标题】:PHPExcel class not found in Zend Autoloader在 Zend Autoloader 中找不到 PHPExcel 类
【发布时间】:2012-02-07 15:23:00
【问题描述】:

我在 Zend 框架中的命名空间上苦苦挣扎(至少我认为这是一个命名空间问题)。

我想将 PHPExcel 集成到我的 Zend 项目中。相关文件结构如下:

/
 -library
   -ABCD
   -PHPExcel
   -Zend
   -ZendX
   -PHPExcel.php

自定义类工作正常,之后

Zend_Loader_Autoloader::getInstance()->registerNamespace('ABCD_');

在引导程序中。此外,这些类都被命名为 ABCD_blahdeblah。

但是,执行 registerNamespace('PHPExcel_') 并不能帮助 Zend 找到合适的类。当我尝试

$sheet = new PHPExcel; 

在控制器中,我收到“找不到类”错误。我猜这是因为 PHPExcel 中的类没有以命名空间前缀命名,或者因为主 PHPExcel.php 文件位于我刚刚声明的命名空间之外。但是 PHPExcel 结构要求它位于其余的 class/font/etc 文件的父目录中。

任何指针将不胜感激。

提前致谢。

【问题讨论】:

  • PHPExcel 是否使用其他类?是不是不能把类重命名为My_PHPExcelApp_PHPExcel,把所有的东西都放在各自的目录下?
  • 它确实使用了其他类,由船夫。这将是一项相当大的重构工作。目前,我只是在控制器中使用“include_once”;这并不理想,但可以工作。

标签: zend-framework namespaces phpexcel


【解决方案1】:

为 PHPExcel 创建一个自动加载器并将其添加到 Zend 自动加载器堆栈。

library/My/Loader/Autoloader/PHPExcel.php:

class My_Loader_Autoloader_PHPExcel implements Zend_Loader_Autoloader_Interface
{
    public function autoload($class)
    {
        if ('PHPExcel' != $class){
            return false;
        }
        require_once 'PHPExcel.php';
        return $class;
    }
}

application/configs/application.ini:

autoloadernamespaces[] = "My_"

然后,在application/Bootstrap.php

protected function _initAutoloading()
{
    $autoloader = Zend_Loader_Autoloader::getInstance();
    $autoloader->pushAutoloader(new My_Loader_Autoloader_PHPExcel());
}

然后你应该能够实例化 PHPExcel - 比如说,在控制器中 - 使用一个简单的:

$excel = new PHPExcel();

唯一棘手的部分是 PHPExcel 如何处理在其自己的文件夹中加载其所有依赖项。如果这样做是明智的——无论是使用require_once basename(__FILE__) . '/someFile.php' 之类的调用,还是使用它自己的自动加载器(不知何故不会妨碍 Zend 自动加载器)——那么一切都应该很酷。 #著名的遗言

【讨论】:

  • 按预期工作 - 现在我也知道如何为其他库做到这一点,谢谢!
  • 我的荣幸。当我最终弄清楚这一点时,它为集成非 PSR-0 库开辟了一个全新的世界,就像我处理的许多遗留代码一样。干杯!
【解决方案2】:

如今,composer 是一种常用工具,但在 2012 年并不那么流行。即使是在 ZF1 中构建的旧项目也可以使用 composer 及其自动加载器。

如何让您的库所有正常工作,而不必每次都向您的application.ini 添加自定义自动加载器?

利用composer的自动加载器

首先,从setting up composer.json 开始。创建完成后,运行composer install 收集所有需要的包并创建composer 的自动加载器。

现在,让我们更新您项目的public/index.php。从现在开始,所有通过 composer 加载的需求都会被自动加载。

<?php

// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'development'));

// Include composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';

/** Zend_Application */
require_once 'Zend/Application.php';

// Create application, bootstrap, and run
$application = new Zend_Application(
    APPLICATION_ENV,
    array( 'config' => APPLICATION_PATH . '/configs/application.ini' )
);

$application->bootstrap();
$application->run();

【讨论】:

    【解决方案3】:

    尝试修改 PHPExcel 自动加载器:

    添加

        if (function_exists('__autoload')) {
            spl_autoload_register('__autoload');
        }
    

    作为 /Classes/PHPExcel/Autoloader.php 中 Register() 方法的前两行,紧接在之前

    return spl_autoload_register(array('PHPExcel_Autoloader', 'Load'));
    

    【讨论】:

      【解决方案4】:

      我在使用 exel-librare (phpxls) 和 pdf-library (fpdf) 时遇到了类似的问题,经过一些不同的尝试后,我刚刚解决了手动从库中包含所需文件并从那里开始的问题。 Booth phpxls 和 fdpd 可以在不干扰 zend 自动加载方法的情况下处理其他所有内容。

      psudo_code 示例如下所示,我返回所需类的对象,然后可以继续使用它。你当然可以选择在构造函数中包含一些东西并从中构建。

          <?php
          class exelClass{
      
              public function exelFunction(){
      
                  require_once 'required_file.php';
      
                  $exelObject = new exelObject();
      
                  return $exelObject->Output();
              }
          }
          ?>
      

      这个解决方案可能不是那么优雅,但我发现它是让不同类型的库共存而没有不同的自动加载器或魔法函数相互干扰的最简单方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-02
        • 1970-01-01
        • 1970-01-01
        • 2017-01-25
        • 2015-12-16
        • 2012-10-31
        • 2015-02-17
        相关资源
        最近更新 更多