php - 如何获取特定命名空间内的所有类名?

标签 php namespaces

我想获取命名空间中的所有类。我有这样的东西:

#File: MyClass1.php
namespace MyNamespace;

class MyClass1() { ... }

#File: MyClass2.php
namespace MyNamespace;

class MyClass2() { ... }

#Any number of files and classes with MyNamespace may be specified.

#File: ClassHandler.php
namespace SomethingElse;
use MyNamespace as Classes;

class ClassHandler {
    public function getAllClasses() {
        // Here I want every classes declared inside MyNamespace.
    }
}

我在 getAllClasses() 中尝试了 get_declared_classes()MyClass1MyClass2 不在列表中。

我该怎么做?

最佳答案

更新:由于这个答案变得有点流行,我创建了一个 packagegist 包来简化事情。它基本上包含了我在这里描述的内容,无需自己添加类或手动配置 $appRoot。它最终可能支持的不仅仅是 PSR-4。

可以在此处找到该软件包:haydenpierce/class-finder .

$ composer require haydenpierce/class-finder

在 README 文件中查看更多信息。


我对这里的任何解决方案都不满意,所以我最终建立了我的类(class)来处理这个问题。 此解决方案要求您是:

  • 使用 Composer
  • 使用 PSR-4

简而言之,这个类试图根据您在 composer.json 中定义的命名空间来确定类在文件系统上的实际位置。例如,在命名空间 Backup\Test 中定义的类可以在 /home/hpierce/BackupApplicationRoot/src/Test 中找到。这是可以信任的,因为将目录结构映射到命名空间是 required by PSR-4 :

The contiguous sub-namespace names after the "namespace prefix" correspond to a subdirectory within a "base directory", in which the namespace separators represent directory separators. The subdirectory name MUST match the case of the sub-namespace names.

您可能需要调整 appRoot 以指向包含 composer.json 的目录。

<?php    
namespace Backup\Util;

class ClassFinder
{
    //This value should be the directory that contains composer.json
    const appRoot = __DIR__ . "/../../";

    public static function getClassesInNamespace($namespace)
    {
        $files = scandir(self::getNamespaceDirectory($namespace));

        $classes = array_map(function($file) use ($namespace){
            return $namespace . '\\' . str_replace('.php', '', $file);
        }, $files);

        return array_filter($classes, function($possibleClass){
            return class_exists($possibleClass);
        });
    }

    private static function getDefinedNamespaces()
    {
        $composerJsonPath = self::appRoot . 'composer.json';
        $composerConfig = json_decode(file_get_contents($composerJsonPath));

        return (array) $composerConfig->autoload->{'psr-4'};
    }

    private static function getNamespaceDirectory($namespace)
    {
        $composerNamespaces = self::getDefinedNamespaces();

        $namespaceFragments = explode('\\', $namespace);
        $undefinedNamespaceFragments = [];

        while($namespaceFragments) {
            $possibleNamespace = implode('\\', $namespaceFragments) . '\\';

            if(array_key_exists($possibleNamespace, $composerNamespaces)){
                return realpath(self::appRoot . $composerNamespaces[$possibleNamespace] . implode('/', $undefinedNamespaceFragments));
            }

            array_unshift($undefinedNamespaceFragments, array_pop($namespaceFragments));            
        }

        return false;
    }
}

关于php - 如何获取特定命名空间内的所有类名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22761554/

相关文章:

c++ - 使用命名空间标准?

xslt - 转换为 SVG 文件时的 XSL 命名空间问题

PHP 和 JavaScript cookie

sql-server - 使用带有子命名空间的 SQL Server 生成 xml

php - WooCommerce 的持续 504 超时

php - 使用 MDBtool linux 连接 PDO

namespaces - CertificateWebRequestHandlerModifierOptions 位于哪个命名空间?

c# - 有条件地选择命名空间进行实例化

php - 更新或插入mysql中每个用户的信息

php - SASS 和/或 LESS - 我可以即时创建动态 CSS 文件吗?