13

Is it possible in the current stable version of the Zend Framework (1.11), to work with application classes using PHP namespaces?

Application\Form\Abc instead of Application_Form_Abc
Application\Model\Xyz instead of Application_Model_Xyz
etc.

Starting from v1.10, ZF supports autoloading namespaces, and it's working fine when including namespaced libraries, but I was unsuccessful when trying to do the same job with application classes.

hakre
  • 193,403
  • 52
  • 435
  • 836
BenMorel
  • 34,448
  • 50
  • 182
  • 322
  • duplicate of http://stackoverflow.com/questions/1691793/how-do-i-use-namespaces-with-zend-framework – Rufinus Jun 28 '11 at 21:57
  • @Rufinus: nope, I did have a look at this question, which is 2 years old. The namespace autoloading support was not out at this time, and the author was asking if it was possible to *modify* ZF to support this feature. I'm asking if *a subset* of this feature is *built-in* now; they're talking about the internal ZF classes, while I just want my **application classes** to use namespaces, I don't care extending ZF's non-namespaced classes. – BenMorel Jun 28 '11 at 22:00
  • you just have to take care of the autoloader, look for doctrine 2.0 integration tutorials, they have use namespaces and have an own autoloader which is used by zend_loader. – Rufinus Jun 28 '11 at 22:06
  • @Rufinus: as I mentioned, the autoloader currently shipped with ZF already handles namespaces. But I'm talking about the ZF-specific mapping from e.g. `Application_Form_Abc` to `/application/forms/Abc.php`, which is different from the standard mapping. – BenMorel Jun 28 '11 at 22:28
  • 1
    This more recent SO question (http://stackoverflow.com/questions/6409424/zend-resource-autoloaders-not-working-for-namespaces) discusses it, but (so far) comes to the conclusion that @Benjamin notes: the ZF1 autoloader *does* handle namespaces, but `Zend_Loader_Autoloader_Resource` *does not*. – David Weinraub Jun 29 '11 at 02:17

3 Answers3

8

Actually there is a simple workaround suggested by Dmitry on the ZF issue tracker:

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    protected function _initAutoloader()
    {
        $loader = function($className) {
            $className = str_replace('\\', '_', $className);
            Zend_Loader_Autoloader::autoload($className);
        };

        $autoloader = Zend_Loader_Autoloader::getInstance();
        $autoloader->pushAutoloader($loader, 'Application\\');
    }
}

Works like a charm for me!

BenMorel
  • 34,448
  • 50
  • 182
  • 322
6

The standard autloader introduced in 1.12 allows you to use namespaces with minimal effort:

require 'Zend/Loader/AutoloaderFactory.php';
Zend_Loader_AutoloaderFactory::factory([
    'Zend_Loader_StandardAutoloader' => [
        'autoregister_zf' => true,
        'namespaces' => [
            'Application' => '/path/to/Application/src',
        ]
    ]
]);

Now you can use Application\Form\Abc instead of Application_Form_Abc & Application\Model\Xyz instead of Application_Model_Xyz etc.

Directory/File structure examples:

path/to/Application/src/Form/Abc.php

<?php
namespace Application/Form;
class Abc {}

path/to/Application/src/Model/Xyz.php

<?php
namespace Application/Model;
class Xyz {}
Gerard Roche
  • 6,162
  • 4
  • 43
  • 69
0

For those wanting your controllers to work and not just the forms and models :) Take a look at the Zend\Controller\Dispatcher\Standard.php:174

public function formatClassName($moduleName, $className)

You would need to swap the _ with "\" as well in order to get the correct class name.

iaskakho
  • 1
  • 2