PHP:如何在使用自动加载器时获取所有类

时间:2016-04-17 11:48:23

标签: php composer-php autoloader

我正在使用composer生成自动加载器:

"autoload": {
  "psr-4": {
    "SomeNamespace\\": "src/SomeDir"
  }
}

我需要创建实现特定接口的所有类的实例。 It's fairly easy不使用自动加载器时,get_declared_classes()与自动加载器的效果不佳。只有在使用自动加载器实例化后才会列出一个类。

3 个答案:

答案 0 :(得分:1)

如果您没有跟踪哪些类存在,自动加载不会帮助您。

但是,如果您尝试包含所有文件并查看哪些类可能会出现错误,那么情况就会大致相同。

无论您尝试做什么:尝试不同的方式。我非常怀疑你在服务一个请求时必须实例化所有这些类。如果你必须扫描接口的所有声明的类,然后为所有这些类创建一个实例,那么对性能不是非常有益。

提供某种注册方法,让应用程序了解您的类。如果你真的必须全部使用它们,那就这样吧。但扫描以前运行的任何代码听起来都不对(你根本没有解释你做了什么)。

答案 1 :(得分:1)

您可以在require_once函数调用之前使用脏hack和get_declared_classes()所有类。

  1. 首先,通过composer dumpautoload --optimize
  2. 将所有课程转储到课程地图
  3. 现在你可以获取作曲家加载器并需要所有文件
  4.     $res = get_declared_classes();
        $autoloaderClassName = '';
        foreach ( $res as $className) {
            if (strpos($className, 'ComposerAutoloaderInit') === 0) {
                $autoloaderClassName = $className; // ComposerAutoloaderInit323a579f2019d15e328dd7fec58d8284 for me
                break;
            }
        }
        $classLoader = $autoloaderClassName::getLoader();
        foreach ($classLoader->getClassMap() as $path) {
            require_once $path;
        }
    
    1. 现在,您可以再次轻松使用get_declared_classes(),这将返回作曲家知道的所有课程
    2. P.S。不要在生产中使用它。

答案 2 :(得分:0)

我在某个目录中找到的所有*Sniff.php类都有类似的用例。

您可以使用Nette\RobotLoader

我的应用中获取灵感的摘录:RobotLoaderFactory + Getting all the classes

对于您的用例

$src = __DIR__ . '/src';

$robotLoader = new Nette\Loaders\RobotLoader\RobotLoader;
$robotLoader->setTempDirectory(__DIR__ . '/temp');
$robotLoader->addDirectory($src);
$robotLoader->acceptFiles = ['*Suffix.php']; // optional to reduce file count
$robotLoader->rebuild();

$foundClasses = array_keys($robotLoader->getIndexedClasses());

// filter in any way