Skip to content

Loading files through autoloading - a possible solution #12

@oprypkhantc

Description

@oprypkhantc

Hey @alekitto.

We stumbled upon your lib and wanted to use it to auto-discover classes in graphqlite. It generally works as expected, but isn't using autoloading. I understand why it's not using autoloading, but there are cases where autoloading is required for the class to function properly.

For example, we have a pre-8.0 enum implementation that uses a custom autoloader to call ::initialize() on enum classes being loaded, which initializes static properties of an enum.

So I dug a little bit deeper to see if there's anything that can be done on your end without Composer actually fixing composer/composer#6987.

What I thought was class-finder could check if the file that it's trying to load is one of the files from files section in composer.json. That's relatively trivial to do, because composer generates a vendor/composer/autoload_files.php file that just returns a list of all files to be loaded. Something like this:

$vendorDir = dirname(
    (new ReflectionClass(\Composer\Autoload\ClassLoader::class))->getFilename()
);
$autoloadedFiles = array_flip(
    require $vendorDir . '/autoload_files.php'
);

Then, when actually trying to load a class, instead of blindly using include_once, it could rely on autoloading to do so, given we first check if the file is contained in $autoloadedFiles:

if (isset($autoloadedFiles[$path]) {
    continue;
}

ErrorHandler::register();
try {
    if (!$this->exists($class)) {
        continue;
    } 
} catch (Throwable) { /** @phpstan-ignore-line */
    continue;
} finally {
    ErrorHandler::unregister();
}

yield $class => $this->reflectorFactory->reflect($class);

I understand this feels hacky. However, this solves a real world problem for us, and possibly more for others that are related to not using autoloading; and to be fair, this entire package is just a big hack around PHP's weird autoloading state.

I can PR these changes if that's something you'd accept.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions