Search code examples
phpnamespacescomposer-phpautoload

Issue with Autoloading and Namespace in PHP using Composer


I'm having difficulty understanding the concept of namespacing in PHP. I should have set

{
   "name": "test/test-namespace",
   "autoload": {
       "psr-4": {
           "Test\\TestNamespace\\": "src/",
           "Test\\TestNamespace\\A\\": "src/A/",
           "Test\\TestNamespace\\B\\": "src/B/",
           "Test\\TestNamespace\\C\\": "src/C/"
       }
   },
   "authors": [],
   "require": {}
}

My directory structure looks like this:

.
├── composer.json
├── index.php
├── src
│   ├── A
│   │   └── a.php
│   ├── B
│   │   └── b.php
│   └── C
│       └── c.php
└── vendor
    ├── autoload.php

As an example, here's the contents of a.php, which is located in the /A folder:

<?php
namespace Test\TestNamespace\A;


class Test_A {
    public function __construct()
    {
        echo 'Test_A';
    }
}

Now, I'm trying to call the classes using namespaces as follows:

<?php
require_once __DIR__ . "/vendor/autoload.php";

use Test\TestNamespace\A\Test_A;
use Test\TestNamespace\B\Test_B;
use Test\TestNamespace\C\Test_C;

$a = new Test_A();
$b = new Test_B();

However, I'm getting the following error message and I'm not sure how to solve the issue:

php index.php         
PHP Fatal error:  Uncaught Error: Class "Test\TestNamespace\A\Test_A" not found in .../PhpstormProjects/test-namespace/index.php:8
Stack trace:
#0 {main}
  thrown in .../PhpstormProjects/test-namespace/index.php on line 8

Fatal error: Uncaught Error: Class "Test\TestNamespace\A\Test_A" not found in .../PhpstormProjects/test-namespace/index.php:8
Stack trace:
#0 {main}
  thrown in .../PhpstormProjects/test-namespace/index.php on line 8

It seems that the classes can't be found, and I'm unsure how to resolve this issue.


Solution

  • According to PSR-4 standards, your class names must match the names of the files for autoloading to work.

    From your example, you're supposed to have Test_A class file name as Test_A.php.

    Also, you don't need to add sub directories under the psr-4 maps. Once you add the top directory, every class under directory A will have the following namespace:

    Class Test\TestNamespace\A\Test_A will be in directory src/A/

    So all you really need to do is have the first map.