Search code examples
phpcomposer-phpautoloadautoloader

Composer, own packages and the story with autoload


I'm currently working on my own packagist package which incorporates another package. I think I didn't quite get the idea of the usage of autoload.

My package is a rest-framework and depends on the AltoRouter. My core needs to load the AltoRouter and since the autoloader is responsible for that I'm including it in my file by using the following:

require_once __DIR__.'/../vendor/autoload.php';

The file structure in my project is as follows:

project-root/
├── src/
|   └── core.php
└── vendor/
    ├── autoload.php
    └── altorouter/

Now this works fine for developing my package but as soon I want to distribute it via packagist (and thus composer) everything goes wrong. As soon I start another project, require my custom package with composer and try to run my package's code, the require_once (in core.php) will screw up everything, since it's pointing to a (now) wrong location.

Is there something I'm doing wrong? Do I have to structure my "package"-project differently?

Solution: Don't include autoload.php in your library-files. Include it in a bootstrap-file (e.g. index.php)


Solution

  • Your library code should generally not be requiring the composer autoloader. Each app that installs your package using composer is responsible for requiring the autoloader according to its own needs. For web applications, that usually happens in an entrypoint script like index.php at the root of the public directory.

    When you're working with your library in isolation, and not as a dependency (e.g. to run a test suite) you can use a separate bootstrapping script that requires the autoloader.

    If you use phpunit, it's simple to set up autoloading for your tests. Just point the bootstrap attribute in phpunit.xml.dist to the composer autoloader file:

    <phpunit bootstrap="vendor/autoload.php">
      ...
    </phpunit>
    

    This way, the composer autoloader will run before your tests, so you won't need to require it in your library code.