Namespaces and Composer
Two students in a school can both be called Maria. "Maria from 7-Rizal" and "Maria from 10-Mabini" are never confused. Namespaces are the section names for your classes.
Real PHP projects have many classes, often one per file, and they use code written by other people: libraries for dates, emails, payments, and more. Two problems come with that:
- Name clashes. Your project has a
Productclass, and so does a library you install. Which one doesnew Product()mean? - Loading files. With 50 class files, writing 50
requirelines at the top of every page is no fun.
Namespaces solve the first problem, and Composer solves the second, while also installing those libraries for you.
The clash
PHP won't allow two classes with the same name:
<?php
class Product {}
class Product {}
// error: Cannot redeclare class ProductNamespaces: section names for classes
A namespace gives your classes a family name. Declare it at the top of the file, right after declare(strict_types=1);:
<?php
declare(strict_types=1);
namespace App\Shop;
class Product
{
public function __construct(
public string $name,
public float $price,
) {
}
}This class's full name is now App\Shop\Product. Namespaces use backslashes \ and are usually built like folder paths: your project's name (often App), then the area of the code. Another library's Product might be Acme\Inventory\Product, and the two never collide.
use: calling it by its short name
Writing new \App\Shop\Product(...) everywhere would be tiring. A use statement at the top of a file says "when I write Product, I mean this one":
use App\Shop\Product;
$pen = new Product("Pen", 12.5);When two classes share a short name, rename one with as:
use App\Shop\Product;
use Acme\Inventory\Product as StockItem;Here's all of that in a single runnable file. (Real projects put each namespace in its own files; one file with several namespaces is just for trying it out.)
<?php
namespace Shop;
class Product
{
public function label(): string
{
return "Product for sale: " . static::class;
}
}
namespace Warehouse;
class Product
{
public function label(): string
{
return "Product in storage: " . static::class;
}
}
namespace Main;
use Shop\Product;
use Warehouse\Product as StoredProduct;
echo (new Product())->label(), "\n";
echo (new StoredProduct())->label(), "\n";
echo (new \Shop\Product())->label(), "\n";Product for sale: Shop\Product
Product in storage: Warehouse\Product
Product for sale: Shop\ProductA name that starts with \, like \Shop\Product, is a fully qualified name: the complete address, which works anywhere without a use. PHP's own built-in functions, like strlen, keep working inside any namespace, so you don't need to do anything special for them.
Composer: PHP's package manager
Composer is the standard tool for PHP projects. It does two jobs:
- Installs packages: libraries other people have published on Packagist (packagist.org), the main PHP package directory, along with whatever those libraries need in turn.
- Loads your classes automatically, so you never write a
requireline for a class again.
Installing Composer
Get it from getcomposer.org. At the time of writing, the current version is Composer 2.10.
- Windows: download and run Composer-Setup.exe from the Download page. It finds your PHP and sets everything up.
- macOS:
brew install composer. - Linux: follow the command-line steps on the Download page.
Check it in a new terminal with composer --version. If Composer complains about a missing zip extension on Windows, remove the ; from extension=zip in your php.ini, as you did for the others in Setting Up.
Installing a package
In your project folder, ask Composer for a package by its name. nesbot/carbon is a popular library for working with dates:
composer require nesbot/carbonComposer downloads it (and the packages it depends on) into a folder called vendor, and records what you installed in two files:
composer.json: the packages your project needs. It's short and made for humans.composer.lock: the exact versions that were installed, so everyone working on the project gets the same ones.
Never edit the files in vendor yourself; Composer manages them. When sharing a project with Git, leave vendor out, since anyone can recreate it by running composer install.
Autoloading your own classes
To have Composer load your own classes too, tell it where they live, in composer.json:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"require": {
"nesbot/carbon": "^3.14"
}
}This says: "a class whose name starts with App\ is in the src folder, and the rest of its name is the path." So App\Shop\Product must be in src/Shop/Product.php. This naming rule is a shared standard called PSR-4, and nearly every PHP project follows it. (The \\ is just how JSON writes a single backslash.)
After changing the autoload section, run composer dump-autoload once, so Composer notices.
The project now looks like this:
my-shop/
├── composer.json
├── composer.lock
├── index.php
├── src/
│ └── Shop/
│ ├── Cart.php
│ └── Product.php
└── vendor/
└── autoload.php (and the installed packages)Using it all
One require line loads Composer's autoloader. After that, any class, yours or a package's, is loaded the moment you first use it:
<?php
declare(strict_types=1);
require __DIR__ . "/vendor/autoload.php";
use App\Shop\Cart;
use App\Shop\Product;
use Carbon\Carbon;
$cart = new Cart();
$cart->add(new Product("Notebook", 45));
$cart->add(new Product("Pen", 12.5));
echo "Total: " . $cart->total() . "\n";
$sale = Carbon::create(2026, 10, 1)->addDays(10);
echo "Sale ends: " . $sale->format("F j, Y") . "\n";With a Cart class in src/Shop/Cart.php that adds up its products' prices, php index.php prints:
Total: 57.5
Sale ends: October 11, 2026No require for Cart, Product, or Carbon. Composer found each file from its namespace.
Try it
Here's a single-file version with two namespaces. Predict each line.
Running PHP here
Running PHP right in the browser is coming to Syntaxia soon. For now, you can read and edit the code here. If you have PHP installed on your computer (see Setting Up), save it as index.php and run it with php index.php.
Check your prediction
Library card for Ana (School\Library\Card)
Canteen card with PHP 150 (School\Canteen\Card)
Library card for Ben (School\Library\Card)
NAMESPACES DONECard means the library card, because of the first use. MealCard is the canteen's Card, renamed with as. The third one uses the fully qualified name. $card::class shows each object's full class name, namespace included. And strtoupper, a built-in function, works fine inside the App namespace.
Try it yourself
- Add a third namespace,
School\Clinic, with its ownCardclass, and use it asHealthCard. - Make a real Composer project: create a folder, add the
composer.jsonabove (without therequirepart), put a class insrc/, runcomposer dump-autoload, and use it fromindex.php. - In that project, run
composer require nesbot/carbon, and print today's date withCarbon::now()->format("l, F j").
Check your understanding
Up next
What should happen when something goes wrong: a missing file, a bad value, a database that's down? PHP's answer is exceptions. Learn to throw and catch them in Errors and Exceptions.
