phpnamespacesfilenotfoundexception

PHP class out of vision in other files despite "use" directive


There is a small class User:

<?php
namespace App\src\entities;

class User{
    //code here
}

I tried acessing this class in another file with "use" keyword.

<?php
namespace App;
use App\src\entities\User;

$user = new User("Test", "test");

IDE can understand that there is a class User and even have given me it with autofilling. However, when i run this code, all i get is Fatal error: Uncaught Error: Class 'App\src\entities\User' not found in /var/www/app/app/public/test.php:5 Stack trace: #0 {main} thrown in /var/www/app/app/public/test.php on line 5

I tried modifying composer.json adding this:

"autoload": {
        "psr-4": {
            "App\\": "app/"
        }
    }

Then i autogenerated files again. That didn't help and nothing has changed.

Why is this happening and what can i do about it? I came to php from C# and am suffering from frustration now.


Solution

  • Different than C# that is compiled, PHP is just loaded.

    So what a linker normally does in the build phase after compiling to object files, does not exists in PHP. PHP has a different mechanism, and it is called class auto loading or commonly autoloading in short (ref).

    That is, if a PHP program is started, it commonly only has a single file (the PHP script), after parsing the PHP code is translated to OP-Codes and fed to the interpreter.

    When you organize a PHP project as a Composer project, Composer takes care of generating an autoloader. The initial PHP script then needs to require that autoloader so that it is active.

    require 'vendor/autoload.php';
    

    Then whenever PHP needs a new class definition, for example the first new User(), the User class has not yet been loaded and then the autoloader will take care to load it.

    Whenever the autoloading does not work (is not in action), it is that the class remains undefined and therefore the class is not found.

    Fatal error: Uncaught Error: Class 'Foo\Bar\Baz' not found in ...

    That's why you first had the error but once requiring the vendor/autoload.php file it went away.

    This only needs to be done once per process, so you often find requiring the autoloader script during bootstrapping.

    The resolution in the IDE is independent to that vendor/autoload.php file - at least IIRC in PhpStorm that is - but it may still read the composer project configuration from composer.json for the PSR namespace roots. But the IDE has another benefit, it can scan just all files and then it knows where each class is. So resolution in the IDE may already work, even if the project configuration has not yet the final autoload configuration (was not a problem in your example) or the autoload.php script was not yet dumped / loaded.