Using Composer and Namespaces in PHP

Pretty much everyone who develops with PHP uses Composer, and if you’ve every used a PHP framework, you’ve seen the namespaces at the tops of files. I knew how to use these things but I didn’t really understand them until I embarked on a few just-for-learning side projects that I started from scratch (i.e. without a framework).


In their own words, Composer is:

“…a tool for dependency management in PHP. It allows you to declare the libraries your project depends on and it will manage (install/update) them for you.”

When you start with a framework, there’s a composer.json file there already, but if you need to make one yourself, it might look something like this:

  "name": "lampstackninja/fromscratch",
  "description": "This is a demo project.",
  "minimum-stability": "stable",
  "license": "proprietary",
  "authors": [
      "name": "Kenn Kitchen",
      "email": "me at"
  "require": {
    "php": ">=8.1",
    "twig/twig": "^3.0",
    "monolog/monolog": "^2.5",
    "psr/log": "^3.0",
    "vlucas/phpdotenv": "^5.4"
  "autoload": {
    "psr-4": {
      "App\\": "src/"
  "require-dev": {
    "phpunit/phpunit": "^9"

This file normally lives in the root folder of your project. The first section provides descriptive information about the project. The second group list publicly-available packages that you plan to use with your project. So far so good, right?

Next we come to “autoload.” We know we want it, but if we have to understand it, we need to understand a little more about PSR-4 and autoloading.

Understanding Autoloading

PSR-4 is the official autoloading standard of the PHP Framework Interop Group, an organization made up of people from major PHP frameworks and projects: in other words, the people who use PHP agreed to work together to self-govern.

In the example above, in my composer.json, I’ve said that I wanted to autoload using the PSR-4 standard, that the root of my namespace will be “App,” and that the location of the files should be “src/” (relative to the location of the composer.json file itself, which should be the project root).

Running composer update from the command line (project root directory) will create a “vendor/” folder in your project with the files from the items listed in your “require” section. It will also create a composer.lock file (more on that in another post).

Now we’re ready to code some autoloading things!

Loading the Loader

Let’s say that, in your project root, you have an index.php file (as most of our projects do). Assuming that this is the topmost file of your project – the single entry point – then you should start with the following:

namespace App;

require_once '../vendor/autoload.php';

In PHP, the namespace statement – when used – has to be the first statement in the file. Since we told composer that our namespace was “App” and this is the top file, that’s what we need here.

Line 4 above is critical: it directs our program to the PHP file that Composer uses to actually do the autoloading.

Using your Code

We’ve all seen the “use” statements at the top of PHP files, but the logic behind them can seem a little cryptic until we dig into Composer and autoloading as we’re doing here.

In the index.php file that we started in the last section, let’s say that we want to use a router class. Perhaps we create a folder in “src/” called “Routes,” and inside of that folder we want to code our new router. That file should start out something like this:

// src/Routes/Router.php

namespace App\Routes;

class Router
  ... code goes here ...

What we’ve done is created a new PHP class file named “Router” and applied the namespace “App\” (meaning its part of our project’s top-level namespace) and “\Routes” (meaning that we want this file and any others relating to routing) to have their own subset of our App namespace.

If we decided, for example, to make some controllers, we might follow a similar pattern. We create a folder in “src/” called “Controllers” and inside of that folder we begin writing code for our controllers:


namespace App\Controllers;

class AppController
  ... code goes here ...

Now we have some code, and we have a structure for our namespaces:

  • App
    • Controllers
    • Routes

Since we’ve updated the map of our namespaces by adding new things, we have to tell Composer. From the command line (again, in the root of the project) run:

composer dumpautoload

Back to our index.php file, if we want to use our new router and controller code, we can now “use” them like this:

namespace App;

require_once '../vendor/autoload.php';

use App\Controllers\AppController;
use App\Routes\Router;

Notice how the use statements are formed from the namespace of the class file plus the name of the class itself.

The Benefits of PSR-4

While it may seem a little complicated at first, there are a number of benefits to using Composer and PSR-4 autoloading.

When I started writing code (no, it wasn’t on stone tablets but there may have been some papyrus involved) we wrote “top down.” Sure, there were functions that could be called to keep the main file cleaner, but it was mostly all in one big, ugly, sequential file, and code organization (which function is where in the giant list?) was always an issue.

By following an agreed-upon standard like PSR-4 – which was developed by people who live with PHP daily! – we can not only improve our own code’s readability but it also gives us a road-map to read everyone else’s (assuming they’re on board with PSR-4).

At a glance at the index.php example above, the use statements make it clear what code from outside of this file is being used. If I need to find the code, I can see that the code for AppController lives in the Controllers folder and the code for Router lives in the Routes folder.

My individual files can live anywhere, meaning I can group files together based on the functions that they serve. I never have to do crazy, failure-prone things like:

require_once '../../../some/file.php';

Finally, because of Composer and the autoloader, all the things are available where ever they’re needed; I just need to “use” them.

originally posted on

Leave a Reply

Your email address will not be published. Required fields are marked *