logo

When Composer can't find a class that exists

Reach for classmap, not files

Joel Clermont
Joel Clermont
2026-08-18

We recently added Meta conversion tracking to an app, and used a Laravel package to quickly bootstrap the functionality. But the first time the app actually tried to send a conversion, it died with an error.

Class "FacebookAds\PII_DATA_TYPE" not found

The confusing part is that the class was right there in the vendor directory. I could browse to it and open it in my editor!

The issue was that Facebook split its SDK across multiple packages, and one of them shipped classes in folders that don't match their namespace. Every class lives in the FacebookAds namespace, but the files sit in nested folders like src/model and src/piiUtil.

By default, Composer's autoloader maps a class name to a file path using PSR-4 rules. So because this package deviated from that standard, I got a "class not found" error for a class that plainly exists.

This isn't hopeless though. Composer gives us some tools to let us tell it where to find the "missing" classes, both by adding an entry to our composer.json file.

The first option is a files entry, which lists individual PHP files.

{
    "autoload": {
        "files": [
            "vendor/facebook/capi-param-builder-php/php/capi-param-builder/src/model/Constants.php",
            "vendor/facebook/capi-param-builder-php/php/capi-param-builder/src/piiUtil/PIIUtils.php"
        ]
    }
}

The second option is a classmap entry, which can point at a whole directory.

{
    "autoload": {
        "classmap": [
            "vendor/facebook/capi-param-builder-php/php/capi-param-builder/src/"
        ]
    }
}

They look similar, but they behave very differently. A files entry loads every listed file on every single request, whether or not the class is ever used. On the other hand, a classmap entry scans the directory once when you run composer dump-autoload, records a class name to file path lookup, and only loads a file the first time its class is actually referenced.

For a feature like this that is only used in specific areas of the app, the classmap approach is a cleaner solution.

Just remember to run composer dump-autoload after any change.

Here to help,

Joel

P.S. An error like this can eat a whole afternoon. If you'd like another set of eyes on a stubborn problem, schedule a call and we'll dig in together.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼
email
No spam. Only real-world advice.