PHP namespacing and spl_autoload_register

diplosaurus picture diplosaurus · Mar 19, 2014 · Viewed 12.5k times · Source

I had spl_autoload_register working fine but then I decided to add some namespacing to bring in PSR2 compliance and can't seem to get it working.

Directory strcuture:

-index.php
-classes/
  -Class1.class.php
  -Class2.class.php
  -Class3.class.php

Each class starts with:

namespace Foo;

Class ClassX {

Index.php:

<?php

spl_autoload_register(function($class) {
    include 'classes/' . $class . '.class.php';
});

$myObj = new Class1();

echo $myObj->doSomething();

This products an error Fatal error: Class 'Class1' not found in /var/www/myApp/index.php on line X

My first thought was that I need to use a namespace with my instantiation, so I changed index.php to:

$myObj = new Foo\Class1();

However, then I get Warning: include(classes/Foo\Class1.class.php): failed to open stream: No such file or directory in /var/www/myApp/index.php on line 6

If I do manual includes everything works fine,include 'classes/Class1.class.php'; and so on.

Answer

diplosaurus picture diplosaurus · Mar 19, 2014

So the problem was that the $class being returned to spl_autoload_register was the namespace\class name, with the backslash intact. So when I instantiated a new object:

$myObj = new Foo\Class1();

The include path became /var/www/myApp/classes/Foo\Class1.php, the backslash breaking the path.

I implemented this to fix the backslash, and it now works, although I do not know why this is necessary.

spl_autoload_register(function($class) {
    include 'classes/' . str_replace('\\', '/', $class) . '.class.php';
});