phpnamespacesautoloadspl-autoload-register

PHP Autoloading in Namespaces


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);

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.