PHP Autoloading in Namespaces

autoload, namespaces, php, spl-autoload-register

Solution

Here's the only right answer.

Every namespace needs its own spl_autoload_register() function.

also, spl_autoload_register() syntax changed in 5.3:

spl_autoload_register(__NAMESPACE__ . "\\className::functionName"));

The following should work:

namespace glue;

require_once 'import.php';

use glue\import as import;
use glue\core\router as router;

$import = new import();

spl_autoload_register(__NAMESPACE__ . "\\$import::load"));

/** Works and echos glue\router **/
$router = new router();

/** Don't do nothing **/
$cheese = \glue\common\is_email($email);

Here is some live code that Just works!

in ../WebPageConsolidator.inc.php:

class WebPageConsolidator
{
    public function __construct() { echo "PHP 5.2 constructor.\n"; }
}

in test.php:

<?php

namespace WebPage;

class MyAutoloader
{
    public static function load($className)
    {
        require '../' . __NAMESPACE__ . $className . '.inc.php';
    }
}

spl_autoload_register(__NAMESPACE__ . "\\MyAutoloader::load");

class Consolidator extends \WebpageConsolidator
{
    public function __construct()
    {
        echo "PHP 5.3 constructor.\n";

        parent::__construct();
    }
}

// Output: 
// PHP 5.3 constructor.
// PHP 5.2 constructor.

So I know it works.

Problem

I have had a slight problem with autoloading in my namespace. As shown on the PHP manual here: http://us.php.net/manual/en/language.namespaces.rules.php you should be able to autoload namespace functions with a full qualified name e.g. \glue\common\is_email(). Thing is I have a function spl_autoload_register(array($import, "load")); within the initial namespace but whenever I try and call \glue\common\is_email() from the initial namespace it will not pass that autoload function but when using new is_email() (in the context of a class) it will. I don't get it the manual says I can autoload from fully qualified names but I can't :. Here's my code: ``` namespace glue; require_once 'import.php'; use glue\import as import; use glue\core\router as router; $import = new import(); spl_autoload_register(array($import, "load")); /** Works and echos glue\router **/ $router = new router(); /** Don't do nothing **/ $cheese = \glue\common\is_email($email); ``` I also tried this code as well: ``` namespace glue; require_once 'import.php'; use glue\import as import; use glue\core\router as router; use glue\common; $import = new import(); spl_autoload_register(array($import, "load")); /** Works and echos glue\router **/ $router = new router(); /** Don't do nothing **/ $cheese = common\is_email($email); ``` and finally this code: ``` namespace glue; require_once 'import.php'; use glue\import as import; use glue\core\router as router; use glue\common\is_email as F; $import = new import(); spl_autoload_register(array($import, "load")); /** Works and echos glue\router **/ $router = new router(); /** Don't do nothing **/ $cheese = F($email); ```

Original source