简体   繁体   中英

PHP classes with a namespace cannot be loaded via spl_autoload_register?

I have a problem in loading classes with spl_autoload_register when a namespace is implemented in a class.

the class autoloader below, but I have no problem loading any class when no namespace is used,

class autoloader
{
    /**
     * Set the property.
     */
    public $directory;
    public $recursive;

    /**
     * Receive the supplied data.
     * @string $directory
     * @array $recursive default: models
     */
    public function __construct($directory, $recursive = array('search' => 'models') ) 
    {
        # Store the data into the property.
        $this->directory = $directory;
        $this->recursive = $recursive;

        # When using spl_autoload_register() with class methods, it might seem that it can use only public methods, though it can use private/protected methods as well, if registered from inside the class:
        spl_autoload_register(array($this,'get_class'));

    }

    private function get_class($class_name)
    {
        # List all the class directories in the array.
        if ($this->recursive)
        {
            $array_directories =  self::get_recursive_directory($this->directory);
        }
        else
        {
            if (is_array($this->directory)) $array_directories =  $this->directory;
            else $array_directories =  array($this->directory);
        }

        # Set the class file name.
        $file_name = 'class_'.strtolower($class_name).'.php';

        # Loop the array.
        foreach($array_directories as $path_directory)
        {
            if(file_exists($path_directory.$file_name)) 
            {
                # There is no need to use include/require_once. Autoload is a fallback when the system can't find the class you are instantiating. 
                # If you've already included it once via an autoload then the system knows about it and won't run your autoload method again anyway. 
                # So, just use the regular include/require - they are faster.
                include $path_directory.$file_name;
            } 
        }

    }

    # However the memory consumption of this can be huge if you have a very large directory tree with only a few matches.
    # @source: http://stackoverflow.com/questions/9294543/search-and-list-specific-directories-only
    public function get_recursive_directory($directory)
    {
        # Create an object that allows us to iterate directories recursively.
        # Stolen from here: 
        # http://www.php.net/manual/en/class.recursivedirectoryiterator.php#102587
        $iterator = new RecursiveIteratorIterator
                    (
                        new RecursiveDirectoryIterator($directory),
                        RecursiveIteratorIterator::CHILD_FIRST
                    );

        # This will hold the result.
        $result = array();

        # Loop the directory contents.
        foreach ($iterator as $path) 
        {

            # If object is a directory and matches the search term ('models')...
            if ($path->isDir() && $path->getBasename() === $this->recursive['search']) 
            {

                # Add it to the result array.
                # Must replace the slash in the class - dunno why!
                $result[] = str_replace('\\', '/', $path).'/';
                //$result[] = (string) $path . '/';

            }

        }

        # Return the result in an array.
        return $result;
    }
}

a tag class for instance,

namespace hello;

class tag extends \core
{
}

now load the class via the autoloader class,

# Autoload the classes from the specific folder.
$autoloader = new autoloader("C:/wamp/www/website/local/applications/master/sides/models/", $recursive = false);

# Instantiate the tag.
$tag = new hello\tag($connection);

result,

: Class 'hello\\tag' not found in on line :类'你好\\标签'用未找到线路

Any idea how I can fix my autoloader class so that I can load the classes whether there is a namespace or not?

EDIT:

The folder where I keep the classes and the class naming,

C:\wamp\www\website\local\applications\master\sides\models\

class_tag.php
class_something.php

Your error is in your get_class() method. $class_name contains the fully qualified classname with it's namespace. In your case you have to strip the namespace from your classname.

$file_name = 'class_'.strtolower(array_pop(explode('\\', $class_name))).'.php';

I highly recommend using PSR-0 standard for autoloading. If you will be using any libraries it is very likely that they are using the same standard and you only have one autoloader.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM