Composer classmap autoload does not load new files in folder
Asked Answered
T

4

25

The following problem: I have defined a classmap in my composer.json:

"autoload": {
    "classmap": [
        "app/controllers",
        "app/models",
        "app/helper.php"
    ]   
}

However, when I create a new file in the "controllers" or "models" folder, it will not load them and I always have to make a composer dump-autoload.

Is this the correct behavior? I thought the autoloader from composer monitors the folder for new files then?

Tereasaterebene answered 2/9, 2014 at 8:31 Comment(0)
F
30

Yes, this is correct behaviour. If you want new classes to be loaded automatically, you have to use either PSR-0 or PSR-4 autoloading.

Generating the classmap requires Composer to know the filename that contains a certain class. This can only be done by parsing the whole source code in the directory and scanning for classes, interfaces and trait definitions.

This usually is a CPU and I/O intensive task, so it is only done when Composer does install/update or (on demand) dumps the autoloader, it is not done with every require "vendor/autoload.php";.

Note that the classmap autoloading is simply there for old legacy codebases that didn't implement at least PSR-0. It is not intended for new code - unless you want to pay the price to dump the autoloader again and again during development.

Fantastically answered 3/9, 2014 at 0:58 Comment(2)
"Note that the classmap autoloading is simply there for old legacy codebases that didn't implement at least PSR-0". Not quite true. See the documentation for dump-autoload: "--optimize (-o): Convert PSR-0/4 autoloading to classmap to get a faster autoloader. This is recommended especially for production, but can take a bit of time to run so it is currently not done by default."Translocate
Optimizing the autoloader is not the same as defining the autoloading scheme. If a future version of PHP offers engine-level support for PSR-4, Composer likely will give up the classmap when optimizing for such a version, but has to keep the classmap if that classmap is the way autoloading is defined.Fantastically
P
13

Go to the root of your server by SSH. Now do the following:

  1. Run ls to list all the files.
  2. You will see composer.lock file; remove the file with rm composer.lock command.
  3. Now run php composer update command.

Depending on your linux type you may have to run php-cli composer update.

Step 3 will create a new composer.lock file and all your classes will be loaded again. Do this anytime you add new classes.

or:

  1. Run composer dump-autoload command.
Procephalic answered 6/3, 2015 at 10:9 Comment(1)
Dont just do this. This will also update all your packages, which might be more then you want.Kalagher
S
0

As already pointed out this is correct behavior. If you want new classes to be loaded automatically, you have to use either PSR-0 or PSR-4 autoloading.

The classmap autoload type specified is composer.json is mainly used by legacy projects that do not follow PSR-0 or PSR-4. I have recently started working on such a project and wanted to try to automatically run the composer dump-autoload command when a new class is created. This is actually tricky without including all of the composer source inside the project. I came up with this just to remind the developer they need to dump the classmap:

$loader = include_once 'vendor/autoload.php';
if ( ! $loader ) {
    throw new Exception( 'vendor/autoload.php missing please run `composer install`' );
}

spl_autoload_register(
    function ( $class ) {
        if ( 'A_Common_Class_Prefix' === substr( $class, 0, 10 ) ) {
            throw new Error( 'Class "' . $class . '"" not found please run `composer dump-autoload`' );
        }
    },
    true
);

This registers another autoloader which is run after composer's autoloader so any classes composer did not find would be passed to it. If the class matches a prefix an exception is throw reminding the developer to re-dump the autoloader and update the classmap.

Symbol answered 11/1, 2019 at 18:31 Comment(0)
R
0

For me, it somehow did not work too with Yii 1 class-map, when I added - required it along with many other libraries present - I don't remember exactly perhaps I manually edited the file or file permissions were to blame, it was not regenerated for some reason, even when I removed the composer.lock and erased completely the vendor folder - perhaps some cache, as far as I remember, but effectively what helped was to install firstly isolatedly only this single library, it generated class-map, then I added all the other remaining libraries separately at once at second step, viola, everything loadable.

Ramble answered 18/10, 2019 at 18:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.