【问题标题】:php namespace auto-load directoryphp命名空间自动加载目录
【发布时间】:2014-11-02 03:50:34
【问题描述】:

我有一个像这样的类结构(树):

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

工作原理:(由 spl_autoload_register 自动加载)

use garcha\html;

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

不能工作:

use garcha\html;

$tag = new Tag('a');

没有实现它:(我不想逐行写每个类文件的use语句,指向类目录并使用没有父命名空间的类)

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

我不喜欢这种方式,因为它很无聊,需要更多时间,不够灵活(你可以更改文件结构、类名等。

简而言之:我正在尝试自动加载命名空间的类目录并在其中使用具有非限定名称的类。

自动加载功能:

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;
    }
}

添加路径:

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

自动加载有效,问题是如何处理

use garcha\html; // class directory

并使用不带前导 html 的类

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

【问题讨论】:

  • 您的self::$pathes 设置为什么
  • 为什么不使用完整的命名空间路径?以后改路径就得改了,use与否
  • @Ggio 我更新了问题
  • @Machavity 想象一下该目录中有超过 10 个类,为每个类写 10 行并不酷:/
  • @GeorgeGarchagudashvili 可能会在您的自动加载器中添加 html 以从 /html 加载所有类

标签: php namespaces spl-autoload-register


【解决方案1】:

您可以尝试不同的解决方案:

首先:您可以在pathes 变量中添加garcha/html,例如::addPath('garcha/html')

第二:尝试在您的自动加载器中使用以下代码

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

glob 基本上会匹配所有以.php 结尾的文件,然后您可以使用它们将它们添加到您的pathes 变量中或仅包含它们。

注意:您需要稍微修改您的自动加载器以在其中使用上述循环。

编辑: 试试这个:

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;
}

【讨论】:

  • 谢谢,但这不是我想要的,因为还会有garcha\validatorgarcha\database 等。包括里面的所有文件,似乎不是一个好主意。这也不值得,因为我只会使用html\TagDatabase\Connection
  • 如果在不加载所有文件的情况下无法完成所需的解决方案,我将继续使用当前的可用性。非常感谢,看来这将是唯一的解决方案,或者为每个类编写使用声明
  • @GeorgeGarchagudashvili 我将其添加为书签,以防有人发布有效的解决方案。我也想在我的应用程序中使用它:)。 aba shen ici
  • გენაცვალე,მადლობა
猜你喜欢
  • 2013-11-25
  • 2014-04-13
  • 2011-08-06
  • 2015-07-15
  • 2012-05-21
  • 1970-01-01
  • 2011-04-08
相关资源
最近更新 更多