# How can this autoloader be improved?

I don't understand the concept of autoloaders, other than the bare minimum, which is that to load a class file when the class is being called. Or as the PHP manual cites it, to avoid having to require multiple time.

I get that, but what I don't understand is the complexity behind almost all the autoloaders which I sought to learn some things from. It's almost impossible to understand what goes on behind the scenes.

Just to understand it a bit more with your help, I made a simple autoloader as you can see below:

class Autoloader
{
private $pathToClass; //register the path function __construct($pathToClass)
{
$this->pathToClass =$pathToClass;
}

public function load($class) { // expload the namespaces ex: foo\bar\tar array(foo, bar, tar)$explode = explode('\\', $class); //get the last exploaded string and append .php so it becomes tar.php$class = $explode[count($explode) - 1].'.php';

// required tar.php in the path it is found ex:
// require '/foo/bar/tar.php' in lowecase to avoid windows/unix conflict
if(file_exists(strtolower($this->pathToClass.$class))){
require strtolower($this->pathToClass.$class);

return true;
}

return false;
}

public function register()
{
spl_autoload_register([$this, 'load']); } }  The class explains itself. It does work, and I just would like to know what I am missing? As you can see, it is the most basic autoloader. What would be the next most important thing you would add to it? Here is how it is instantiated: $myLibLoader = new Autoloader(__DIR__.'/foo/bar/');
$myLibLoader->register();$foo =  new foo();


• The access modifier for your constructor is missing.

function __construct...
public function __construct


Although no specified access modifier on methods means that PHP chooses public automatically (see PHP docs), I would add it for consistency.

• Your autoloader does not cope with namespaces. You might want to read PSR-0, a specification stating how autoloaders should cope with namespaces, folders and filenames.

• Do not add random newlines.

public function load($class) { // expload the namespaces ex: foo\bar\tar array(foo, bar, tar) public function load($class)
{
// expload the namespaces ex: foo\bar\tar array(foo, bar, tar)


// expload the namespaces ex: foo\bar\tar array(foo, bar, tar)
//get the last exploaded string and append .php so it becomes tar.php


Be consistent! I suggest using a space after //.

• Be specific in variable names. $pathToClass lets me think that the string points to a specific class file. It does however point to a directory containing class files. I suggest using $classDir. $class is also an edge case since it does contain more than a single class name. • You don't need explode if you only wish to extract the class name. Use strrpos(): $classFilename = substr($class, strrpos($class, '\\') + 1) . '.php';

• Don't apply strtolower two times. Just save the result in a temporary variable. It makes your code DRY.

• Since you declare pathToClass private anyway, consider marking the class final. Some arguments are provided in an article Final should be Default for Classes in Java (the same principles not only apply to Java, but also to many other languages including PHP).

• Mark your load method private. It's an implementation detail, which shouldn't be accessible from outside the class.

• Your load method is not required to return a boolean value. Returning true or false is not bad per se, maybe you will want to encapsulate the autoloading mechanism further and throw exceptions depending on the return value.

Elaborating on the PSR-0 specification

\Doctrine\Common\IsolatedClassLoader => /path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php
\Symfony\Core\Request => /path/to/project/lib/vendor/Symfony/Core/Request.php
\Zend\Acl => /path/to/project/lib/vendor/Zend/Acl.php
\Zend\Mail\Message => /path/to/project/lib/vendor/Zend/Mail/Message.php

\namespace\package\Class_Name => /path/to/project/lib/vendor/namespace/package/Class/Name.php
\namespace\package_name\Class_Name => /path/to/project/lib/vendor/namespace/package_name/Class/Name.php


Roughly speaking, your code is missing the following aspects:

• Taking the namespace into account and using it to build a directory hierarchy.
• Transforming underscores in class names to a directory hierarchy as well.
• Ok, I got the second point. Seems pretty straight forward. I should use DIRECTORY_SEPERATOR to make my autoloader namespace friendly. As some frameworks use underscore _ and others use  But the first point is tough to understand. Does it mean if I am loading a class as \$foo = new foo\bar\tar\register then, that class register or register.php should be stored inside foo\bar\tar folder? should the full namespace be identical to the folder structure? – robue-a7119895 Aug 3 '14 at 21:04
• @CONtext Exactly, the qualifier foo\bar\tar\register requires you (according to PSR-0) to load register.php from the path foo/bar/tar. Note that underscores only play a role in class names. They remain in package names as is. – ComFreek Aug 3 '14 at 21:07