I have a strange problem in production, where composer dump-autoload --no-dev --classmap-authoritative
produces a classmap autoloader where classes defined using class_alias
are not dumped. For example, take this two files from a real Symfony Bundle:
class_alias
The autoloader contains the first class:
root@09cc7fdd330c:/var/www/html# cat vendor/composer/autoload_classmap.php | grep -i SonataDoctrineBundle
'Sonata\\Doctrine\\Bridge\\Symfony\\Bundle\\SonataDoctrineBundle' => $vendorDir . '/sonata-project/doctrine-extensions/src/Bridge/Symfony/Bundle/SonataDoctrineBundle.php',
'Sonata\\Doctrine\\Bridge\\Symfony\\SonataDoctrineBundle' => $vendorDir . '/sonata-project/doctrine-extensions/src/Bridge/Symfony/SonataDoctrineBundle.php',
... but not the second one.
As a consequence, I'm getting errors in production:
PHP Fatal error: Uncaught Error: Class 'Sonata\Doctrine\Bridge\Symfony\SonataDoctrineSymfonyBundle' not found in /var/www/html/src/Kernel.php:38
Question is: why I cannot autoload class SonataDoctrineSymfonyBundle
?
(I can fix this problem changing this specific class of course, but I don't know where class_alias
maybe used across the entire vendor
directory).
The composer dump-autoload
command with the --classmap-authoritative
command line argument prevents any other auto-loading next to the classmap.
This mechanism is part of the Composer Autoloader optimization¹, more specifically, it is the Optimization Level 2/A: Authoritative class maps².
This option [-a, --classmap-authoritative] says that if something is not found in the classmap, then it does not exist and the autoloader should not attempt to look on the filesystem according to PSR-4 rules.
When Composer generates the class-map, it does not take files with class_alias()
directives into account³. That means, classes which names only appear as parameters to calls of class_alias()
do not become part of the class-map.
As it seems you don't have the requirement to use this autoloader optimization and it is incompatible with the class_alias
use, an alternative is to use Composer autoload optimization level 1 only:
$ composer dump-autoload --no-dev --optimize
(use of --optimize
(short: -o
) command line argument)
Otherwise it might work using concrete classes instead of class_alias()
, but this depends if the library in use supports a different, more static alternative. If so however, then generating the "real" classes before dumping the classmap may help you retain the optimization level 2/A.
¹ Composer Autoloader optimization
² Optimization Level 2/A: Authoritative class maps
³ at least not at the time of writing this answer per its source, with additional discussion of the topic in Support for class aliases #5873