How to get all class names inside a particular namespace?

Update: Since this answer became somewhat popular, I’ve created a packagist package to simplify things. It contains basically what I’ve described here, without the need to add the class yourself or configure the $appRoot manually. It may eventually support more than just PSR-4.

That package can be found here: haydenpierce/class-finder.

$ composer require haydenpierce/class-finder

See more info in the README file.


I wasn’t happy with any of the solutions here so I ended up building my class to handle this. This solution requires that you are:

  • Using Composer
  • Using PSR-4

In a nutshell, this class attempts to figure out where the classes actually live on your filesystem based on the namespaces you’ve defined in composer.json. For instance, classes defined in the namespace Backup\Test are found in /home/hpierce/BackupApplicationRoot/src/Test. This can be trusted because mapping a directory structure to namespace is 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.

You may need to adjust appRoot to point to the directory that contains 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("https://stackoverflow.com/", $undefinedNamespaceFragments));
            }

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

        return false;
    }
}

Leave a Comment