Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPExcel class not found in Zend Autoloader

I am struggling with namespaces in Zend Framework (at least I think it's a namespace issue).

I want to integrate PHPExcel into my Zend project. Relevant file structure is as follows:

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

Custom classes work fine, after

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

in the bootstrap. Also, those classes are all named ABCD_blahdeblah.

However, doing registerNamespace('PHPExcel_') doesn't help Zend find the appropriate classes. When I try

$sheet = new PHPExcel; 

in the controller, I get a "Class not found" error. I am guessing that this is either because classes in PHPExcel aren't named with the namespace prefix, or because the main PHPExcel.php file sits outside of the namespace I've just declared. But the PHPExcel structure demands that it sit in the parent directory of the rest of the class/font/etc files.

Any pointers would be greatly appreciated.

Thanks in advance.

like image 486
yycroman Avatar asked Jan 11 '12 08:01

yycroman


3 Answers

Create an autoloader for PHPExcel and add it to the Zend autoloader stack.

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

And in application/configs/application.ini:

autoloadernamespaces[] = "My_"

Then, in application/Bootstrap.php:

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

Then you should be able to instantiate PHPExcel - say, in a controller - with a simple:

$excel = new PHPExcel();

The only sticky part is all of this is how PHPExcel handles loading all its dependencies within its own folder. If that is done intelligently - either with calls like require_once basename(__FILE__) . '/someFile.php' or with its own autoloader that somehow doesn't get in the way of the Zend autoloader - then all should be cool. #famouslastwords

like image 155
David Weinraub Avatar answered Nov 04 '22 08:11

David Weinraub


Nowadays composer is a frequently used tool that wasn't so popular back in 2012. Even older projects built in ZF1 can make use of composer and its autoloader.

How to get all your libraries to work without having to add custom autoloaders to your application.ini each time?

Make use of composer's autoloader

First, start with setting up composer.json. Once created, run composer install to gather all required packages and create composer's autoloader.

Now, let's update your project's public/index.php. From now on all requirements that are loaded via composer will be autoloaded.

<?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();
like image 40
halfpastfour.am Avatar answered Nov 04 '22 08:11

halfpastfour.am


Try modifying the PHPExcel autoloader:

Add

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

as the first two lines of the Register() method in /Classes/PHPExcel/Autoloader.php, immediately before

return spl_autoload_register(array('PHPExcel_Autoloader', 'Load'));
like image 1
Mark Baker Avatar answered Nov 04 '22 06:11

Mark Baker