Chris Brown
Chris Brown

Reputation: 4635

Issue with Composer's Autoloader

I'm starting work on a new mini-framework project, which I have in a local GIT repo on my machine. I've set up a test project that pulls in the local repo via Composer, however the autoloader isn't working as expected (Fatal Error: Class X not found errors). This is the first time I've used autoloading outside of what is automatically generated (e.g. when using an existing framework) and despite reading around, I can't seem to solve this.

Package

In an attempt to get this working, the package only contains a src directory with a single App.php class on top of the composer.json file in the root.

composer.json

{
  "name": "myvendor/framework",
  "description": "Framework Description",
  "license": "MIT",
  "authors": [
    {
      "name": "Joe Bloggs",
      "email": "[email protected]"
    }
  ],
  "autoload": {
    "psr-0": {
      "Framework": "src/"
    }
  }
}

Project

composer.json

{
  "repositories": [
    {
      "type": "vcs",
      "url" : "../Framework"
    }
  ],
  "require": {
    "myvendor/framework": "dev-master"
  }
}

This successfully clones the local repo and adds the code to the vendor directory.

The namespace is also successfully added to Composer's autoload_namespaces.php file like so;

vendor/composer/autoload_namespaces.php

'Framework' => array($vendorDir . '/myvendor/framework/src'),

When I attempt to load the App class however using the following code, I get the error;

web/index.php

<?php

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

$app = new \Framework\App();

Upvotes: 0

Views: 141

Answers (1)

Wouter J
Wouter J

Reputation: 41934

You're using the psr-0 specification for the class loader. This means that the full namespace has to be visible in the file structure. The prefix only tells the autoloader were to look for this namespace.

So in your case, you configured that the "Framework" namespace is available in the "src/" directory. This means that the class \Framework\App should life in src/Framework/App.php. In your case, it exists in src/App.php. This means that the autoloader cannot find your class.

However, there is a class loader specification that does what you want: psr-4. This is also the recommended specification (psr-0 might be removed in the future). With PSR-4, the file structure only includes the namespaces after the configured prefixes. So when doing "psr-4": { "Framework\": "src/" }, a class called \Framework\App should life in src/App.php and a class called \Framework\Some\Special\App should life in src/Some/Special/App.php.

Upvotes: 2

Related Questions