Composer PSR-4 autoloading "class not found" debug

5.3k Views Asked by At

Yes another question about the "class not found" error. Either I am missing something, or I misunderstood the PSR-4 logic.

My composer library directory sturcture:

"Scanner" => "src" => "Test.php"

Test.php

namespace MyNS;

class Test
{
}

composer.json

"autoload": {
        "psr-4": {
            "MyNS\\": "src/"
        },
}

So, now I load the library in my project with composer and try using it.

require_once("../vendor/autoload.php");

$test = new MyNS\Test();

Which always results in

"Fatal error: Uncaught Error: Class 'MyNS\Test' not found."

. What am I missing? I am staring at this for days now. I have changed folders, I have changed folder names, I have changed uppper to lower and vise versa. Nothing seems to work.

I am using PHP 7.2.2 and Composer version 1.2.2

Even tried this:

require_once("../vendor/autoload.php");

use MyNS\Test;

$scanner = new Test();

Update

I debugt the Composer ClassLoader.php file (findFileWithExtension($class, $ext)) method and apparently my files are never loaded because I get put an echo "Done" and a die(); at the end of this method which means the file is not found and thus not loaded. What is wrong with my composer.json?

{
    "name": "test/test",
    "type": "library",
    "description": "",
    "keywords": ["php"],
    "homepage": "",
    "license": "MIT",
    "authors": [
        {
            "name": "",
            "email": "",
            "homepage": "",
            "role": ""
        }
    ],
    "require": {
        "php": ">=7.2.2"
    },
    "autoload": {
        "psr-4": {
            "MyNS\\": "src/"
        }
    }
}
2

There are 2 best solutions below

2
On

i think the problem is in your namespace declaration

you calling the class from MyNS but class namespace is namespace MyNS\PSR4;

require_once("../vendor/autoload.php");

$test = new MyNS\Test();

// it should be new MyNS\PSR4\Test();

and make sure, your class file in same directory which you mentioned in composer autoload file

also you have to run dump-autoload command for any change in classnames

you can visit for this autoload feature

6
On

To debug what is happening open ClassLoader.php file then go where findFileWithExtension() method is defined to add an echo statement:

# vendor/composer/ClassLoader.php:386

foreach ($this->prefixDirsPsr4[$search] as $dir) {
    if (file_exists($file = $dir . $pathEnd)) {
        return $file;
    }
    // Add this line
    echo $file, PHP_EOL;
}

Do not do composer dumpautoload after you manually modified above file until we are done.

Now by executing your PHP file you will see something similar to this at the very beginning of output:

path/to/project/vendor/composer/../../src/Test.php

Which is:

path/to/project/src/Test.php

So this is the file that composer is looking for and should contain something like this:

namespace MyNS;

class Test { }

If there is an issue in including the file then it means you have to care about three things:

  1. Path and filename
  2. Namespace used in file
  3. Class name used in file (class name should be the same as filename)