Search code examples
phpcomposer-phpautoloadpsr-4

Cannot load Classes residing in the same folder with PSR-4


I am trying to wrap my head around composer/psr-4 autoloading since I am new to it.

My project has the following structure:

| ProjectName
  |- src      
  |  |- MainComponent
  |    |- MainClass.php
  |  |- Component1
  |    |- Foo.php
  |    |- Bar.php
  |  |- Component2
  |    |- Baz.php
  |- tests
  |  |- FooTest.php
  |  |- ...
  |- vendor
  |  |- [...]
  |  |- ...     
  |- composer.json
  |- phpunit.xml.dist

In my composer.json I have the following psr-4 entry:

"autoload": {
    "psr-4": {
        "MyName\\ProjectName\\": "src/"
    }
}

I have completed my first components and have namespaced classes in Foo.php like this:

namespace MyName\ProjectName\Component1;

class FooClass 
{
   ...
}

Now I want to use the FooClass in Bar.php (which resides in the same folder):

namespace MyName\ProjectName\Component1;

$foo = new FooClass();

And I get the following error:

Fatal error: Class 'MyName\ProjectName\Component1\FooClass' not found in
/path/to/Bar.php

The same error is thrown when trying with the fully qualified name:

use MyName\ProjectName\Component1\FooClass;

$foo = new FooClass();

The weird thing is that PHPUnit can resolve namespaces correctly since my tests get loaded and executed correctly, using the same exact statement as above.
This is my tests/FooTest.php:

use MyName\ProjectName\Component1\FooClass;

class FooTest extends PHPUnit_Framework_TestCase
...


$ phpunit
OK (15 tests, 383 assertions)

What am I doing wrong?


Solution

  • Your class names are wrong. As you can read in PSR-4 rfc class names must be equal to file names.

    So when you have path to class like: src/Component1/Foo.php

    Your namespace must looks like: \MyName\ProjectName\Component1 and class name must be:

    class Foo { ... }
    

    And in imports:

    use MyName\ProjectName\Component1\Foo;