PSR-4 autoloader Fatal error: Class not found
Asked Answered
B

1

22

I have my project structure like so:

src/
   ├─ Model/
      └─ User.php

My User.php file looks like this:

<?php

namespace Bix\Model;
    
class User {

And my composer.json autoloader is this:

"autoload": {
  "psr-4": {
     "Bix\\": "src/"
   }
}

Finally my bootstrap.php is this:

use Bix\Model\User;
    
// PSR-4 Autoloader.
require_once "vendor/autoload.php";

However if I try and create a new User(), I get the error Fatal error: Class 'User' not found in /var/www/public/api/v1/index.php on line 8

Looking at the composer autoload_psr4.php file it looks ok:

// autoload_psr4.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname(dirname($vendorDir));
    
return array(
    'XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'),
    'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
    'KeenIO\\' => array($vendorDir . '/keen-io/keen-io/src'),
    'Bix\\' => array($baseDir . '/src'),
); 

Can anybody point out where I am going wrong with the above?

Benzyl answered 9/5, 2015 at 6:24 Comment(0)
R
32

First of all, Linux (I'm not sure which PC you use) is case-sensitive. In your autoloading, you defined src/bix, while it is src/Bix.

But more importantly, with PSR-4, the specified namespace prefix is not included in the directory structure (to avoid directories containing just one directory). In your case, if you configure "Bix\\": "src/", a class Bix\Model\User should be located in src/Model/User.php.


EDIT: You're misunderstanding PHP namespaces. In PHP, you're not saying "import everything from Bix\Model into the global namespace for this file" with use Bix\Model;. Instead, it means: "Alias Model in this file to Bix\Model".

So you should either do:

require_once "vendor/autoload.php";

use Bix\Model;

$user = new Model\User();

or:

require_once "vendor/autoload.php";

use Bix\Model\User;

$user = new User();
Riddick answered 9/5, 2015 at 8:43 Comment(8)
I updated the composer.json to this: "Bix\\": "src/" and the folder structure to this: src/Model/User.php however there I still get the error 'class User not found'Benzyl
@Benzyl after you update autoload configuration, you have to run composer dump-autoload to update the autoloaderRiddick
I have done this already. I updated my question with the new folder/structure autoloader.Benzyl
Going with either of your suggestions still doesn't seem to be working. I've updated my question to use your second method.Benzyl
@Benzyl you're doing new User() in bootstrap.php?Riddick
Yes -- I'm now getting this 'fatal error: Class 'Bix\Model\User' not found'Benzyl
All figured -- my src/ folder is actually in public/src, all I needed to do was update my composer.json to "Bix\\": "public/src/" and it worked like a charm. Thanks very much for helping me understand psr-4!Benzyl
Thanks for your answer, also adding that if you are looking to autoload the current directory you can do this: "Foo\\": "" without including any slashes.Dardanus

© 2022 - 2024 — McMap. All rights reserved.