How do I use PHP namespaces with autoload?


Question

I get this error when I try to use autoload and namespaces:

Fatal error: Class 'Class1' not found in /usr/local/www/apache22/data/public/php5.3/test.php on line 10

Can anyone tell me what I am doing wrong?

Here is my code:

Class1.php:

<?php

namespace Person\Barnes\David
{
    class Class1
    {
        public function __construct()
        {
            echo __CLASS__;
        }
    }
}

?>

test.php:

<?php

function __autoload($class)
{
    require $class . '.php';
}

use Person\Barnes\David;

$class = new Class1();

?>
1
93
4/2/2013 12:12:08 PM

Accepted Answer

Class1 is not in the global scope.

See below for a working example:

<?php

function __autoload($class)
{
    $parts = explode('\\', $class);
    require end($parts) . '.php';
}

use Person\Barnes\David as MyPerson;

$class = new MyPerson\Class1();

Edit (2009-12-14):

Just to clarify, my usage of "use ... as" was to simplify the example.

The alternative was the following:

$class = new Person\Barnes\David\Class1();

or

use Person\Barnes\David\Class1;

// ...

$class = new Class1();
112
11/6/2016 8:11:48 PM

As mentioned Pascal MARTIN, you should replace the '\' with DIRECTORY_SEPARATOR for example:

$filename = BASE_PATH . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
include($filename);

Also I would suggest you to reorganize the dirrectory structure, to make the code more readable. This could be an alternative:

Directory structure:

ProjectRoot
 |- lib

File: /ProjectRoot/lib/Person/Barnes/David/Class1.php

<?php
namespace Person\Barnes\David
class Class1
{
    public function __construct()
    {
        echo __CLASS__;
    }
}
?>
  • Make the sub directory for each namespace you are defined.

File: /ProjectRoot/test.php

define('BASE_PATH', realpath(dirname(__FILE__)));
function my_autoloader($class)
{
    $filename = BASE_PATH . '/lib/' . str_replace('\\', '/', $class) . '.php';
    include($filename);
}
spl_autoload_register('my_autoloader');

use Person\Barnes\David as MyPerson;
$class = new MyPerson\Class1();
  • I used php 5 recomendation for autoloader declaration. If you are still with PHP 4, replace it with the old syntax: function __autoload($class)

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon