opcache.preload, and the class that could not be preloaded

Preloading 900 classes, and a fatal error at startup about a class that could not be resolved.

// preload.php
$files = (new SymfonyComponentFinderFinder())
    ->files()->in(__DIR__ . '/src')->name('*.php');

foreach ($files as $file) {
    opcache_compile_file($file->getRealPath());
}

// Fatal error: Class AppContractsHandler not found
// — an interface in a package that was NOT in the finder path.
// preloading a class links its parents and interfaces
// eagerly, and an unresolvable one aborts the whole preload.

The linking is what makes preloading fast and what makes it fragile: a class is only usable preloaded if everything it extends and implements is also preloaded, so the set has to be closed under inheritance. Adding the vendor directory to the finder fixes it and roughly triples the memory. We settled on preloading the application namespace plus an explicit list of framework base classes, which was 40% of the benefit for a tenth of the trouble.