Search code examples
phpautoloader

Will PHP Autoloader load when calling a class constant?


I have a class that defines some class constants. It looks something like this phony class for simplicity.

class MyThing {
  const BORIS = 'Yeltsin';
}

I'm registering the directory that the class is located like so.

AutoLoader::registerDirectory('lib');

I'm using PHP's autoloader and it works as expected, except when I'm trying to call this class const.

If I do this.

MyThing::BORIS

I get this.

Undefined class constant 'BORIS'

I think this is how the autoloader is supposed to work, but I wanted to know if I'm correct.

I'm using this AutoLoader class, which was chosen before I started working at this company, but it seems to work.

<?php

/**
 * Autoloading class.
 * From http://jes.st/2011/phpunit-bootstrap-and-autoloading-classes/
 * as per the author comment:
 * Jess Telford says:
 *   December 21, 2013 at 4:01 am
 *   Public Domain – do with it whatever you want :)
 *
 * This class will compare classnames to the filename without extensions (.class.php or .php) registered
 *
 * This means that only a class per file can be loaded and only if the class name is identical (case sensitive) to the file name
 *
 */

class AutoLoader {

    static private $classNames = array();

    /**
     * Recursively store all .class.php and .php files found under $dirName in the autoloader
     *
     * @param String $dirName has to be a valid path
     */
    public static function registerDirectory($dirName) {

        $di = new DirectoryIterator($dirName);
        foreach ($di as $file) {

            if ($file->isDir() && !$file->isLink() && !$file->isDot()) {
                self::registerDirectory($file->getPathname());
            } elseif (substr(strtolower ($file->getFilename()), -10) === '.class.php') {
                $className = substr($file->getFilename(), 0, -10);
                AutoLoader::registerClass($className, $file->getPathname());
            }elseif (substr(strtolower ($file->getFilename()), -4) === '.php') {
                $className = substr($file->getFilename(), 0, -4);
                AutoLoader::registerClass($className, $file->getPathname());
            }
        }
    }

    public static function registerClass($className, $fileName) {
        AutoLoader::$classNames[$className] = $fileName;
    }

    public static function loadClass($className) {
        if (isset(AutoLoader::$classNames[$className])) {
            require_once(AutoLoader::$classNames[$className]);
        }
     }

}

spl_autoload_register(array('AutoLoader', 'loadClass'));
?>

Update: My original question said that calling spl_autoload('MyThing') solved my problem, it didn't.


Solution

  • In short, yes, autoloader is called for statics.

    You could test this yourself:

    /index.php

    <?php
    
        class Init {
            function __construct() {
                spl_autoload_register(array($this, 'loadClass'));
                echo MyThing::BORIS;
            }
            function loadClass($className) {
                $possible_file = 'classes/' . strtolower($className) . '.php';
                echo 'Autoloader called for ' . $className . '<br />';
                if(file_exists($possible_file)) {
                    require_once($possible_file);
                    return true;
                }
                return false;
            }
        }
    
        new Init();
    

    /classes/mything.php

    <?php
    
        class MyThing {
            const BORIS = 'Yeltsin';
        }
    

    Output

    Autoloader called for MyThing
    Yeltsin