Skip to content

PHP Tutorial Composer

PSR-4 Autoloading with Composer

Lesson 254 of 369 2 min read By Deepak Paswan Updated Oct 5, 2026

You know the rule from PSR-4 Autoloading Basics: a namespace prefix maps to a base folder. Here is how to set it up with Composer, step by step.

1. The folder layout

Text
PLAIN
my-app/
├── composer.json
├── public/
│   └── index.php
└── src/
    ├── Service/
    │   └── Greeter.php
    └── Model/
        └── User.php

2. composer.json

data.json
JSON
{
    "name": "demo/my-app",
    "require": {
        "php": "^8.2"
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

The key "App\\" is the namespace prefix (with the backslash doubled for JSON). The value "src/" is the folder it maps to.

3. The classes

src/Service/Greeter.php
PHP
<?php

declare(strict_types=1);

namespace App\Service;

use App\Model\User;

final class Greeter
{
    public function greet(User $user): string
    {
        return "Hello, " . $user->name();
    }
}
src/Model/User.php
PHP
<?php

declare(strict_types=1);

namespace App\Model;

final class User
{
    public function __construct(private string $name) {}

    public function name(): string
    {
        return $this->name;
    }
}

4. Generate the autoloader

terminal
BASH
composer dump-autoload

(Or composer install, which does it too.)

5. Use the classes

public/index.php
PHP
<?php

declare(strict_types=1);

require __DIR__ . "/../vendor/autoload.php";

use App\Model\User;
use App\Service\Greeter;

echo (new Greeter())->greet(new User("Ana"));
Output
OUTPUT
Hello, Ana

There is not a single require for a class. Composer’s autoloader finds both classes from their names.

Multiple prefixes

data.json
JSON
{
    "autoload": {
        "psr-4": {
            "App\\": "src/",
            "Database\\Seeders\\": "database/seeders/"
        }
    }
}

Tests: autoload-dev

Test classes should not be loaded in production. Put them in autoload-dev:

data.json
JSON
{
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    }
}

Fixing “class not found”

SymptomCheck
Class "App\Service\Greeter" not foundDoes the file src/Service/Greeter.php exist, with the exact capitalisation?
Works on Windows, fails on LinuxA capital letter differs between the class and the file name
New namespace not foundDid you add it to composer.json and run composer dump-autoload?
Wrong namespace line in the fileThe namespace must equal the prefix plus the folder path

A quick way to see what Composer knows:

terminal
BASH
composer dump-autoload -o
php -r 'require "vendor/autoload.php"; var_dump(class_exists("App\\Service\\Greeter"));'

Checking a mapping

index.php
PHP
<?php
function expectedFile(string $class): string
{
    $relative = substr($class, strlen("App\\"));

    return "src/" . str_replace("\\", "/", $relative) . ".php";
}

echo expectedFile("App\\Model\\User");
Output
OUTPUT
src/Model/User.php

If the class file is not at the expected path, the autoloader cannot find it.

info
Why this matters in Laravel
A new Laravel project already has "App\\": "app/" in composer.json. When you add a class in app/Services/, it works at once, because of exactly this PSR-4 mapping.