3

I have a problem with composer auto loader. Currently working on a application which was developed about 10 years back. The folder structure of 2 libraries which are currently used in the project do not comply the psr0 and psr4 auto loading rules.

The structure after the composer install looks as follows

Example 1

Folder path: /vendor/AppBook/ORS/class/model/Country

Filename: class.Country.php

PHP Class name: Country

Example 2

Folder path: /vendor/AppBook/ORS/class/model/Country

Filename: class.CountryCollection.php

PHP Class name: CountryCollection

Please advise what should I do in order that composer auto loader can detect these files.

Thank you in advance

shobekhan
  • 171
  • 1
  • 2
  • 15

2 Answers2

2

From the docs:

You can use the classmap generation support to define autoloading for all libraries that do not follow PSR-0/4. To configure this you specify all directories or files to search for classes.

Example:

{
    "autoload": {
        "classmap": ["src/", "lib/", "Something.php"]
    }
}

You can still add composer.json to your legacy libraries and define classmap autoloading type for them.

Jakub Zalas
  • 35,761
  • 9
  • 93
  • 125
  • if I add autoload in the composer.json of legacy libraries it works – shobekhan Apr 21 '16 at 21:47
  • But if i add in composer.json of my project it does not work "repositories": [ { "type": "package", "package": { "name": "shoaib/test", "type": "package", "version": "master", "source": { "url": "https://github.com/shobekhan/test.git", "type": "git", "reference": "master" }, "autoload": { "classmap": ["Cache/"] } } } ] – shobekhan Apr 21 '16 at 21:47
  • You need to put the "autoload" section in composer.json of your shoaib/test package. Alternatively, if you don't have control over the package you could try defining it at the top level of your composer.json, but I'm not sure if that's gonna work. – Jakub Zalas Apr 22 '16 at 08:53
  • I realized that adding autoload classmap settings in my project json file was not adding the autoload classmap settings to the composer.lock file when I was doing composer update. What I did then is that i removed the package and added it again. This time the autoload classmap settings were properly shown and the project could find the files. I don't know if there is a better way to do this in composer. – shobekhan Apr 22 '16 at 10:12
1

You can rename these files to make them compatible to PSR-4 (unlikely because that requires using namespaces - in 10 years old code?) or PSR-0. Additionally, you have to remove any explicit loading of these files via include, include_once, require or require_once because the file names changed.

PHP will autoload these classes by their class name. This will possibly run into issues if the case sensitivity in the class name is not respected everywhere. Example:

class UpperCase {}

$a = new upperCase();

The autoloading would try to find a file ending with upperCase.php, which will not match the PSR-0 required UpperCase.php, so the code will fail. However, this will work, making the situation not better:

class UpperCase {}

$b = new UpperCase();
$a = new upperCase();

The reason is that PHP treats class names case insensitive, so once a class is loaded, you can use any case in it's name. It is only the first occurrence in your code path that has to match. The problem is to be sure where this really is, so essentially it has to be correct everywhere.

Yes, the classmap feature is the easier way. But you'd still want to remove include/require calls to optimize the performance a bit, so you have to touch the code anyway. And despite it's age, it has to be maintained - so why not do it fully, switching to a well-known autoloading standard. It will help you in the long run when you have to maintain PSR-0/4 compatible classes and this old code in parallel.

Sven
  • 69,403
  • 10
  • 107
  • 109