Custom composer namespace doesn't find class

Kamafeather picture Kamafeather · Dec 4, 2014 · Viewed 13.3k times · Source

I'm trying to use my custom namespace for my personal classes.

The directory structure is (as usual):

    my_project/
      - src/
         |- myComponent.class.php
         \- myWrapper.class.php
      - vendor
         |- OtherLibrary
         \- Symfony
      - composer.json
      - index.php

in my composer.json I specify my own namespace with:

"autoload": {
    "psr-0": {
        "my_namespace\\": "src/"
    }
}`

then in my PHP code I have something like:

myComponent.class.php

namespace my_namespace;

class myComponent
{
 .... code
}

index.php

namespace my_namespace;

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

$component = new myComponent();

Running this I get a:

Fatal error: Class 'my_namespace\myComponent' not found in /path_to_root/my_project/index.php on line 5

while...

  • I would expect myComponent to be searched under my_project/src/, as specified in the composer.json and as defined into vendor/composer/autoload_namespaces.php ('my_namespace\\' => array($baseDir . '/src')).

  • I would expect to directly call my custom myComponent, when I define the namespace to my own namespace. Am I wrong?

What's wrong in my code and my assumptions? How should I fix it?

Answer

Sven picture Sven · Dec 6, 2014

You found the errors yourself, but here is a quick collection of what the useful autoload directives in Composer do:

  1. PSR-0 converts the class name into a path name (underscores and backslashes from namespaces are converted into a directory separator), adds ".php" at the end, and tries to find this file in the path that you have given in the composer.json file. A class myNamespace\myClass and "psr-0":{"myNamespace\\": "src"} will try to load src/myNamespace/myClass.php.
  2. PSR-4 only works with namespaces. It removed the namespace prefix given in composer.json from the full class name, and the remainder is converted into a path, ".php" added at the end, and searched in the path given. A class myNamespace\myClass and "psr-4":{"myNamespace\\": "src"} will try to load src/myClass.php.
  3. Classmap autoloading will work by scanning all the files for classes, interfaces and traits (everything that can be autoloaded), and compiles an array map of it. It works with any file name schema and any directory layout, but try to avoid it because it will need an update to the map every time you add a new class. Also, it takes time to scan the files while installing, and it takes some CPU and memory to load and hold that map.