phpspl-autoload-registerspl-autoloader

spl_autoload with namespace php


I am makeing a small framework for scheduled job that are run by a nodejs external process. I would like to use an auto loader but for some reason data is not getting to it. I am also using namespaces. Here is what my folder structure looks like:

Library
  |_ Core
     |_ JobConfig.php
  |_ Utilities
     |_ Loader.php
  |_ Scheduled
     |_ SomeJob.php
  |_ Config.php

My Config.php just has some definitions and an instance of my Loader.php.

Loader.php looks like:

public function __constructor()
{
    spl_autoload_register(array($this, 'coreLoader'));
    spl_autoload_register(array($this, 'utilitiesLoader'));
}

private function coreLoader($class)
{
    echo $class;
    return true;
}

private function utilitiesLoader($lass)
{
    echo $class;
    return true;
}

So for my SomeJob.php I am including Config.php and then try to instantiate JobConfig.php when it fails. My namespaces look like Library\Core\JobConfig and so on. I am not sure if this is the best approach without the ability to bootsrapt things. But I am not seeing the echo's from the loader before it fails.

Edit:

I tried the sugestion by @Layne but did not work. I am still getting a class not found and seems like the class in not getting in the spl stack. Here is a link to the code


Solution

  • If you actually use namespaces in the same way you're using your directory structure, this should be rather easy.

    <?php
    namespace Library {
        spl_autoload_register('\Library\Autoloader::default_autoloader');
    
        class Autoloader {
            public static function default_autoloader($class) {
                $class = ltrim($class, '\\');
    
                $file = __DIR__ . '/../';
                if ($lastNsPos = strrpos($class, '\\')) {
                    $namespace = substr($class, 0, $lastNsPos);
                    $class     = substr($class, $lastNsPos + 1);
                    $file .= str_replace('\\', '/', $namespace) . '/';
                }
    
                $file .= $class . '.php';
                include $file;
            }
        }
    }
    

    Put that into your Library directory and require it on a higher level. Hopefully I didn't mess that one up, didn't test it.

    EDIT: Fixed path.