1
votes

I am having very hard times understanding how to use autoloading by psr-4.
After loading vagrant and setting and testing all variables in Homestead.yaml I have prepared a file structure as the following:

\app
   \folder
      -- test.php
   \vendor
       \composer
       -- autoload.php
   -- index.php
   -- composer.json

and the following are my codes:

index.php

<?PHP 
namespace app;

require('vendor/autoload.php');

$object = new folder\test();

composer.json

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

test.php

<?php 
namespace app\folder;

class test 
{
    function __construct ()
    {
        echo 'construction done right.';
    }
}

But, after trying to visit the page, these are the error message displayed on the page:

(!) Fatal error: Uncaught Error: Class 'app\folder\test' not found in /home/vagrant/web/sites/app/index.php on line 6
( ! ) Error: Class 'app\folder\test' not found in /home/vagrant/web/sites/app/index.php on line 6

Would you help me understand and fix this error?

4

4 Answers

2
votes

It doesn't work because you have told Composer that the classes from the app namespace are in the app subdirectory but there is no app subdirectory.

The entire application is stored in the app directory and it's name doesn't really matter for the application. The classes of the app namespace are stored in the current directory and the sub-namespaces are stored in subdirectories with the same name.

Accordingly, your composer.json file should read:

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

Or, to be more clear, you can put . (the current directory) as the location of the app\ namespace:

"autoload": {
    "psr-4": {
        "app\\": "."
    }
}

After you make the change run composer dump-autoloader in the main application directory and it will start working.

2
votes

To fix it for your current setup, use the following:

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

Your composer.json is in the app-directory, so there's no subdirectory named app to reference.


I would actually recommend to change your directory structure to the following:

  \app
     \src
     \folder
       -- test.php
       -- index.php
     \vendor
       \composer
         -- autoload.php
     -- index.php
     -- composer.json

And then in composer.json, set the following:

"autoload":{
    "psr-4":{
        "app\\": "src"
    }
}

This makes sure that all files belonging to your 'app' namespace are contained within a single subdirectory.


Finally, I would recommend you to use a vendor namespace to prevent conflicts, and to use the naming guidelines from PSR-2.

0
votes

I think you won't need PSR-4 just add classmap

classmap parameter for example :

"autoload": {        
    "classmap": [
        "app"
    ]
}

After adding this run composer dump-autoload and you should see a number of classes being added.

Hope this helps.

-1
votes

in composer.json try to set

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

then do execute this command

composer dump-autoload -o