Cees-Jan

- Post source at 🐙

Utilizing composer's classloader to locate a class

Composer and Packagist have fundamentally changed the PHP package landscape by providing a central package registry. And a tool to easily install package listed in that registry and autoload them using PSR-04. But the composer tooling can be used for more then just installing and autoloading files. We'll explore one of them in this post.

Composer

Locating a file

For a project I need to parsed PHP classes and I'm using nikic/php-parser, which only accepts a string. (Fair enough it isn't it's responsibility to find a class for me.) Composer to the rescue!

Locating autoload.php

Now this is the hardest part: Locate the autoload.php file (which is just a intermediary file between you and the real autoload file). One can fairly safely assume that it is always located at vendor/autoload.php, but where that is relatively to your current file is the tricky part. In the package I'm working on the following code detects the location of autoload.php. First it tries ../vendor/autoload.php for when it is just the package, and ../../../vendor/autoload.php for when it is used in a project.

private function locateClassloader()
{
    foreach ([
        dirname(__DIR__) . DS . 'vendor' . DS . 'autoload.php',
        dirname(dirname(dirname(__DIR__))) . DS . 'autoload.php',
    ] as $path) {
        if (file_exists($path)) {
            return require $path;
        }
    }

    throw new RuntimeException('Unable to locate class loader');
}

Locating the file we want to parse

Since we have the class loader from autoload.php we can utilize that to file a class we want to use by calling findFile, a method composer uses to a requested class for autoloading:

$classLocation = $this->locateClassloader()->findFile($classToFind);

We now have the location of the class, as found by Composer in $classLocation. Or false when it couldn't find it.

Bonus: Parsing the file

$ast = (new ParserFactory)->create(ParserFactory::PREFER_PHP7)->parse(file_get_contents($classLocation));

Categories: PHP - Composer - Short Post Tags: PHP - Composer - Short Post