24
votes

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?

4

4 Answers

29
votes

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.

11
votes

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.
0
votes

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.

0
votes

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.