How to include a library to a Zend Framework 2 application using namespace based autoloading?

10,219

Solution 1

Edit init_autoloader.php and change the if ($zf2Path) { section to be:

if ($zf2Path) {
    if (isset($loader)) {
        $loader->add('Zend', $zf2Path);
    } else {
        include $zf2Path . '/Zend/Loader/AutoloaderFactory.php';
        Zend\Loader\AutoloaderFactory::factory(array(
            'Zend\Loader\StandardAutoloader' => array(
                'autoregister_zf' => true,
                'namespaces' => array(
                    'MyNamespace' => __DIR__ . '/vendor/MyNamespace',
                ),                    
            )
        ));
    }
}

Note the addition of the MyNamespace key within the Zend\Loader\StandardAutoloader section.

Solution 2

In addition to Rob's answer, some other ways to autoload a custom library

First, make sure your folder structure is psr0 compliant

A typical structure for the mythical psr0 compliant MyNamespace library used in the examples

vendor/
    MyNamespace/
        lib/
            MyNamespace/
                FooClass.php
                BarClass.php

Include from a Module.php file using getAutoloaderConfig

public function getAutoloaderConfig()
{
    return array(
        'Zend\Loader\StandardAutoloader' => array(
            'namespaces' => array(
                'MyNamespace' => __DIR__ . '/../../vendor/MyNamespace/lib/MyNamespace',
            ),
        ),
    );
}

Directly in index.php using the AutoloaderFactory to configure the StandardAutoloader

// Setup autoloading
require 'init_autoloader.php';

Zend\Loader\AutoloaderFactory::factory(array(
    'Zend\Loader\StandardAutoloader' => array(
        'namespaces' => array(
            'MyNamespace' => __DIR__ . '/../vendor/MyNamespace/lib/MyNamespace',
        ),
    )
));

You could even do the same in a ./config/autoload/ file

<?php    
// file ./config/autoload/namespaces.local.php

Zend\Loader\AutoloaderFactory::factory(array(
     'Zend\Loader\StandardAutoloader' => array(
         'namespaces' => array(
             'MyNamespace' => __DIR__ . '/../../vendor/MyNamespace/lib/MyNamespace',
         ),
     )
));

A further alternative to include your lib is to edit vendor/composer/autoload_namespaces.php

<?php

// autoload_namespaces.php generated by Composer

$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);

return array(
    'Zend\\' => $vendorDir . '/zendframework/zendframework/library/',
    'MyNamespace\\' => $vendorDir . '/MyNamespace/lib/',
);
Share:
10,219
automatix
Author by

automatix

Updated on July 16, 2022

Comments

  • automatix
    automatix over 1 year

    I created a subfolder MyNamespace in /vendor/ (is it the correct place for own libraries?) and want to use classes like MyNamespace\Mvc\Router\MyCustomRouter in my application. How can I include this library to my namespace based autoloading?

    • Crisp
      Crisp over 10 years
      Possible duplicate of -> stackoverflow.com/questions/8559107/…
    • automatix
      automatix over 10 years
      I've tried so, how here shown (with Module#getAutoloaderConfig() and 'MyNamespace' => __DIR__ . '/../../vendor/MyNamespace'), but my classes cann still not be found.
    • Crisp
      Crisp over 10 years
      Did you create a Module.php file in /vendor/MyNamespace/ to do that?
    • automatix
      automatix over 10 years
      No, I didn't. But it's not a Module, it's a library -- like ZF. The ZF library folder also has no Module class in it.
    • Crisp
      Crisp over 10 years
      The ZF library uses the standard autoloader, the accepted answer on the linked page describes adding your own library using zends autoloader by placing the code in index.php (obviously change the namespace and path to match your own lib)
    • Crisp
      Crisp over 10 years
      There's actually a lot of ways to do this. You could just add your namespace and path to vendor/composer/autoload_namespaces.php (assuming composer is in use). Honestly though, if the lib is going to be used with Zend Mvc, why not make it a module? The skeleton app is set up to look for modules in vendor anyway.
    • automatix
      automatix over 10 years
      Yes, it would be a good simple possiblity to the library as module, but it is not a module. OK, I've tried vendor/composer/autoload_namespaces.php out ('MyNamespace' => $vendorDir . '/MyNamespace',). The error is still there.
    • automatix
      automatix over 10 years
      If I add 'MyNamespace' => __DIR__ . '/../../vendor/MyNamespace', to the array in Application\Module#getAutoloaderConfig() and/or OtherModule\Module#getAutoloaderConfig() and call a class from the library (use MyNamespace\Path\To\MyClass; $test = new MyClass();) in a view, the server returns an error 502.
    • Crisp
      Crisp over 10 years
      sounds like your namespace isn't psr0 compliant, assuming a path of vendor/MyNamespace/src/MyNamespace for composers autoload_namespaces you would use 'MyNamespace' => $vendorDir . '/MyNamespace/src/', and in a modules getAutoloadConfig() it would be 'MyNamespace' => __DIR__ . '/../../vendor/MyNamespace/src/MyNamespace'
    • automatix
      automatix over 10 years
      I had defined the incorrect library path: 'MyNamespace' => $vendorDir . '/MyNamespace', for the folder /vendor/MyNamespace. The correct path for this folder would be 'MyNamespace' => $vendorDir,. Now I've corrected this: 'MyNamespace' => $vendorDir . '/MyNamespace/library', for /vendor/MyNamespace/library/MyNamespace and it works. Thank you for your help!
    • automatix
      automatix over 10 years
      Please make an answer from your comment with autoload_namespaces. It will be usefull for other and I'll get a possibility to thank you in form of an answer-acceptation.