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

PHP: How to get all classes when using autoloader

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

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

我需要为实现特定接口的所有 classes 创建实例。 It's fairly easy 不使用自动加载器时,但是 get_declared_classes() 不能很好地使用自动加载器。只有在使用自动加载器实例化后,它才会列出 class。

如果您不跟踪存在哪些 类,自动加载将无济于事。

但是,如果您尝试包含所有文件并查看哪些 类 会从中产生,那么情况几乎是一样的,这时您可能会遗漏一个文件。

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

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

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

  1. 首先通过 composer dumpautoload --optimize
  2. 将所有 classes 转储到 class 映射
  3. 现在您可以获取作曲家加载器并需要所有文件
    $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(),return 所有 class 作曲家都知道

P.S。不要在生产中使用它。

我在某个目录中找到的所有 *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