phppackagecomposer-phppsr-4

Why this Simple case of psr-4 not working with composer


I am trying to understand how psr-4 works using composer. These are the contents of my composer.json file

{
    "autoload": {
        "psr-4": {
            "Vehicle\\Car\\":"src/"
        }
    }
}

The Folder Structure is given below (please note I am using windows 10, so directory name casing should not matter I think) The folder where I have created 'vendor' folder is inside D:\temp\composer_test

D:\
  temp\
  composer_test\
    test.php
    composer.json
    composer.lock
    vendor\
      vehicle\
        car\
          src\
            Tire.php
      

Contents of test.php

require __DIR__ . '/vendor/autoload.php';
$tire = new Vehicle\Car\Tire();

Contents of Tire.php

<?php
namespace Vehicle\Car;
class Tire {
    public function __construct()
    {
        echo "initialize Tire\n";
    }
}

But when I run the code (snapshot below) . I see error

D:\temp\composer_test>php test.php

PHP Fatal error: Uncaught Error: Class 'Vehicle\Car\Tire' not found in D:\temp\composer_test\test.php:3 Stack trace: #0 {main} thrown in D:\temp\composer_test\test.php on line 3

I Don't know what is wrong I am doing. Problem is when I install any other standard package I can use it successfully which seems like using the same format


Solution

  • Your composer.json should be:

    {
        "autoload": {
            "psr-4": {
                "Vehicle\\":"src/vehicle/"
            }
        }
    }
    

    Your directory structure should be:

    D:\
      temp\
      composer_test\
        test.php
        composer.json
        composer.lock
        src\
          vehicle\
            car\
                Tire.php
    

    Make sure to run composer dump-autoload to re-general the autoload files.

    Also your namespace does not make much sense, naming your namespace Vehicle would mean that you only have vehicles in your repo. Usually you would name your namespace based on your project name, could be your brand or your username, or something more generic such as App.

    So this would make more sense:

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

    then you have:

    D:\
      temp\
      composer_test\
        test.php
        composer.json
        composer.lock
        src\
          vehicle\
            car\
                Tire.php
          plane\
            ...
    

    and test.php

    require __DIR__ . '/vendor/autoload.php';
    $tire = new App\Vehicle\Car\Tire();