objects namespaces and application architecture

Autoloading

Autoloading is how PHP finds class files automatically when code first refers to a class. Without autoloading, every file would need a long list of require statements.

Modern PHP projects normally use Composer's autoloader. Frameworks such as Laravel and Symfony rely on it. When you see require __DIR__ . '/vendor/autoload.php';, that line loads Composer's generated autoload file.

Why Autoloading Exists

Before autoloading, code often looked like this:

PHP example
<?php

declare(strict_types=1);

require __DIR__ . '/src/Billing/Invoice.php';
require __DIR__ . '/src/Billing/InvoiceRepository.php';
require __DIR__ . '/src/Billing/MarkInvoicePaid.php';

That is fragile. Every new class needs another require, and files must be included in the right order.

Autoloading lets PHP ask a registered function to load a class when it is first used.

PHP example
<?php

declare(strict_types=1);

spl_autoload_register(function (string $class): void {
    $prefix = 'App\\';
    $baseDirectory = __DIR__ . '/src/';

    if (!str_starts_with($class, $prefix)) {
        return;
    }

    $relativeClass = substr($class, strlen($prefix));
    $file = $baseDirectory . str_replace('\\', '/', $relativeClass) . '.php';

    if (is_file($file)) {
        require $file;
    }
});

You usually do not write this yourself in production projects because Composer generates a robust autoloader for you. The example shows the basic idea.

Composer PSR-4

PSR-4 is the common convention for mapping namespaces to folders.

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

With that rule, this class name:

App\Billing\Domain\Invoice

maps to this file:

src/Billing/Domain/Invoice.php

The namespace and folder structure should match. That is why moving a class often means updating its namespace too.

Loading Composer's Autoloader

A front controller, CLI script, or test bootstrap usually loads Composer's autoloader once:

PHP example
<?php

declare(strict_types=1);

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

After that, classes can be found by namespace according to Composer's generated map.

When dependencies are installed or autoload rules change, Composer updates the generated files inside vendor/composer/. In normal development, composer install, composer update, or composer dump-autoload handles that.

Autoloading And use

use statements do not load files.

PHP example
<?php

declare(strict_types=1);

namespace App\Billing\Application;

use App\Billing\Domain\Invoice;

final class MarkInvoicePaid
{
    public function handle(Invoice $invoice): void
    {
    }
}

The use statement only tells PHP that the short name Invoice means App\Billing\Domain\Invoice. Composer's autoloader still needs to be available to load the file when the class is used.

Class Not Found Errors

Autoloading mistakes often produce errors such as:

Class "App\Billing\Domain\Invoice" not found

Common causes include:

  • the file does not exist
  • the namespace inside the file does not match the class name
  • the filename casing does not match on a case-sensitive filesystem
  • Composer's autoload rules do not include the folder
  • vendor/autoload.php was not required
  • autoload files need regenerating after changing composer.json

Debug these errors by checking the fully qualified class name, the file path, the namespace declaration, and the Composer autoload config.

Classmap And Files Autoloading

Composer supports more than PSR-4. You may also see classmaps and files autoloading.

Classmap autoloading maps discovered classes directly to files. It can be useful for legacy code that does not follow PSR-4.

Files autoloading always includes specific files. It is sometimes used for global helper functions.

{
  "autoload": {
    "files": [
      "src/helpers.php"
    ]
  }
}

Use files autoloading sparingly. Classes and namespaced functions are usually easier to manage.

What You Should Be Able To Do

After this lesson, you should be able to explain that autoloading loads class files automatically, describe how PSR-4 maps namespaces to folders, understand the role of vendor/autoload.php, and debug common class-not-found errors.

For junior work, this matters because many PHP errors during setup, refactoring, and deployment are autoloading errors. Knowing the namespace-to-file mapping saves a lot of guesswork.

Practice

Practice: Map Namespaces To Files

Create a short autoloading note for a project using Composer PSR-4.

Task

Given this Composer rule:

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

Write the expected file path for these classes:

  • App\Billing\Domain\Invoice
  • App\Courses\Application\PublishCourse
  • App\Shared\Domain\EmailAddress

Then write a small PHP front-controller snippet that loads Composer's autoloader.

Check Your Work

Confirm:

  • namespace segments after App\ become folders under src/
  • the class short name becomes the filename
  • the front controller requires vendor/autoload.php

Afterward, list two likely causes of a class-not-found error.

Show solution
App\Billing\Domain\Invoice -> src/Billing/Domain/Invoice.php
App\Courses\Application\PublishCourse -> src/Courses/Application/PublishCourse.php
App\Shared\Domain\EmailAddress -> src/Shared/Domain/EmailAddress.php

A front controller or CLI entrypoint loads Composer's autoloader once:

PHP example
<?php

declare(strict_types=1);

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

After that, Composer can load classes that match the configured namespace mapping.

Two likely causes of a class-not-found error are a namespace that does not match the file path, or forgetting to regenerate Composer's autoload files after changing composer.json.