Namespaces, Composer and autoloading

PHP · Practical · 14 min

Composer is how every modern PHP project gets its dependencies and loads its classes.

A namespace groups classes under a prefix so names don't clash: namespace App\Billing; at the top of a file, then use App\Billing\Invoice; (or use ... as Alias) where you need it. Invoice::class gives the fully qualified name as a string.

Composer is PHP's package manager. composer init creates composer.json; composer require monolog/monolog adds a dependency, downloads it into vendor/ and records exact versions in composer.lock. Commit the lock file for applications so every machine installs the same versions; run composer install to reproduce them and composer update to move to newer versions within your constraints. ^3.5 means "3.5 or later, below 4.0".

Composer also writes an autoloader. With PSR-4 you map a namespace prefix to a directory:

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

Now App\Billing\Invoice is loaded from src/Billing/Invoice.php the first time it is used. Include vendor/autoload.php once in your entry script and never write require for classes again. Run composer dump-autoload after changing the mapping.

Dev-only tools go in require-dev (composer require --dev phpunit/phpunit). In production, install with composer install --no-dev --optimize-autoloader. Packages are discovered on Packagist; their binaries land in vendor/bin/.

Example

# Shell: create a project with a dependency and PSR-4 autoloading
composer init --name=acme/shop --no-interaction
composer require brick/money
composer require --dev phpunit/phpunit

# composer.json now contains (edit "autoload" by hand):
#   "require": { "brick/money": "^0.10" },
#   "autoload": { "psr-4": { "Acme\\Shop\\": "src/" } }
composer dump-autoload

# src/Cart.php:      namespace Acme\Shop; final class Cart { ... }
# public/index.php:  require __DIR__ . '/../vendor/autoload.php';
#                    $cart = new Acme\Shop\Cart();

composer install --no-dev --optimize-autoloader   # production
vendor/bin/phpunit --version                      # tools live in vendor/bin

Remember

  • Namespaces prevent name clashes; use imports them
  • composer.lock pins exact versions: commit it for apps
  • PSR-4 maps a namespace prefix to a folder so classes load automatically

Watch out for

  • Editing files inside vendor/; they are overwritten on the next install.

Check yourself

  1. With "App\\": "src/" in psr-4, where must class App\Http\Router live?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: getcomposer.org/doc/01-basic-usage.md