Composer with PSR-4 autoloading: classes from namespace not loading
Asked Answered
O

1

13

I have the follow project structure:

- root
|- src <- Application specifc source
  |- [...]
|- tests
  |- [...]
|- Vendor
  |- myusername <- shared packages for all projects
    |- src
      |- MyNamespace
        |- File.php
  |- autoload.php
  |- test.php
|- composer.json

composer.json already have a PSR-4 entry:

"autoload": {
     "psr-4": {
         "MyNamespace\\":"myusername/src"
     }
}

/Vendor/test.php

<?php
require 'autoload.php';

$file = new MyNamespace\File();
echo $file->isDone();

Vendor/myusername/src/MyNamespace/File.php

<?php
namespace MyNamespace;

class File
{
    public function isDone()
    {
        return 'Done!';
    }
}

But I always get fatal error Fatal error: Class 'MyNamespace\File' not found in [...]

Are the composer settings or file structure correct? What I can do?

EDIT 1:

I can load external vendors fine

Oswin answered 3/4, 2014 at 14:12 Comment(3)
Have you tried putting your directory with sources outside of Vendor? I usually have project structure like sth/src/MyNamespace/... and sth/Vendor/...Womenfolk
This is a shared vendor for all of my projects, not the project source, so, it is in Vendor directory.Oswin
@Womenfolk I have updated the project structure to avoid confusion.Oswin
R
16

There are 2 things wrong with your code.

You are using PSR-4 wrong.

They removed the need to embed the namespace in your folders, making a cleaner footprint in your project folder.

PSR-0
vendor/<VendorName>/<ProjectName>/src/<NamespaceVendor>/<NamespaceProject>/File.php

PSR-4 (See that they removed the namespaces folders? Because you already reference that in composer.json
vendor/<VendorName>/<ProjectName>/src/File.php

So in your case it would be:

Vendor/myusername/src/File.php

Your composer.json is invalid

         "MyNamespace\\":"myusername/src"

Doesn't include the full path to the directory with your project's code. It should be like this:

"autoload": {
     "psr-4": {
         "MyNamespace\\": "Vendor/myusername/src"
     }
}

but the best way to store your files would be outside the vendor directory, as that is used by automatically downloaded libraries, instead choose a different "development" directory:

"autoload": {
     "psr-4": {
         "MyUsername\\MyProject\\": "src/myusername/myproject/src"
     }
}

Thanks to Sven in the comments.

Reason answered 3/4, 2014 at 14:39 Comment(3)
Hey! I have made confusion with PSR-0 and 4, I'm wrong with my namespaces :cOswin
A few seconds before your reply I have solved structuring the project correctly, and verifying that composer will find files from root directory instead of vendor directory. All fine now (:Oswin
Never ever define the autoloading in the main composer.json with a path that goes into vendor. Assuming that Composer will manage the packages, it would be the task of that specific package to declare the autoloading for itself. Which would be a different root path then, without any vendor/myusername/myproject prefix.Inoue

© 2022 - 2024 — McMap. All rights reserved.