简体   繁体   中英

php namespace auto-load directory

I've a class structure (tree) like this:

- garcha/
|   - html/
|       Tag.php
|       VTag.php
|       etc..

What works: (auto-loaded by spl_autoload_register )

use garcha\html;

$tag = new html\Tag('a');

Can't work:

use garcha\html;

$tag = new Tag('a');

To achieve it without: (I don't want to write each class file's use statement line by line, something to point to the class directory and use classes without parent namespace)

use garcha\html\Tag;
use garcha\html\VTag;
... 

I don't like this way because, it's boring, need more time, less flexible ( you may change file structure, class name etc.. )

In a nutshell: I'm trying to auto-load namespaced class directory and use classes in it with unqualified names.

Auto-loader function:

class AutoLoader 
{
    protected static $pathes = array();

    /**
     * add pathes
     * 
     * @param string $path
     */
    public static function addPath($path) 
    {
        $path = realpath($path);

        if ($path) 
        {
            self::$pathes[] = $path . DIRECTORY_SEPARATOR;
        }
    }

    /**
     * load the class
     * @param string $class
     * @return boolean
     */
    public static function load($class) 
    {
        $classPath = $class.'.php'; // Do whatever logic here

        foreach (self::$pathes as $path) 
        {
            if (is_file($path . $classPath)) 
            {
                require_once $path . $classPath;

                return true;
            }
        }

        return false;
    }
}

Adding path:

AutoLoader::addPath(BASE_PATH.DIRECTORY_SEPARATOR.'vendor');

auto-loading works, the question is about how to handle

use garcha\html; // class directory

and use classes without leading html

$tag = new Tag('p'); // not $tag = new html\Tag('p');

You could try different solutions:

First: you can add garcha/html in your pathes variable like ::addPath('garcha/html')

Second: try to use the following code in your auto loader

foreach (glob("garcha/*.php") as $filename)
{
    require_once $filename;
}

glob basically will match all files that end with .php and then you can use them to either add them to your pathes variable or just include them.

Note: you would need to slightly modify your autoloader to use above loop in it.

Edit: Try this:

public static function load($class) 
{
    // check if given class is directory
    if (is_dir($class)) {
       // if given class is directory, load all php files under it
       foreach(glob($class . '/*.php') as $filePath) {
          if (is_file($filePath)) 
          {
             require_once $filePath;

             return true;
          }
       }
    } else {
       // otherwise load individual files (your current code)
       /* Your current code to load individual class */
    }

    return false;
}

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