The Composer has become the standard in PHP to handle Dependency Management to re-use existing packages, libraries, and modules submitted at a central repository manager i.e. Packagist. We can find almost all the major packages and modules for PHP on Packagist and include them in the project using Composer.
The previous tutorial i.e. How To Install Composer On Windows provided the steps required to install Composer on Windows. This tutorial provides the steps required to autoload the project classes using Composer.
Notes: This tutorial covers only the PSR-4 way to autoload the classes using namespaces.
You may also follow How To Install PHP 7 On Windows, How To Install PHP 7 On Ubuntu 20.04 LTS, How To Install PHP For Nginx On Ubuntu 20.04 LTS, How To Install Composer On Windows, How To Install Composer On Ubuntu 20.04 LTS, and Hello World Program In PHP Using NetBeans.
Why Autoloading?
We can use autoloading to include the PHP classes in the file without using the require or include. This makes it much easy to simply use the classes defined and declared in other files. Ideally, we can follow one Class/Interface per file and use namespaces to split the classes and interfaces according to the project feature. We must also follow the Camel Case naming convention as the standard to name the files and classes and the file name should be the same as that of the Interface or Class to easily identify them. Also, use a single word for a namespace without capital letters.
Project Structure
You can follow the project structure as shown below as an exercise to continue with this tutorial. I have kept is simple and minimal to just understand using namespaces, interfaces, and classes.
vehicles
src
design
IVehicle.php
ICar.php
ITruck.php
impl
Vehicle.php
Car.php
Truck.php
web
index.php
composer.json
Create the directory structure and files as shown above.
Install Composer
In this step, we will install the Composer specific to the project by creating the composer.json file. Update the composer.json file as shown below. I have kept the required information of the project i.e. name, description, and also specified the minimum version of PHP to be used for it. You may omit the testing packages specified by me i.e. codeception and phpunit.
{
"name": "vehicles/website",
"description": "The website project to show vehicles.",
"minimum-stability": "stable",
"autoload": {
"psr-4": {
"vehicles\\": "src/"
}
},
"require": {
"php": ">=7.2.0"
},
"require-dev": {
"codeception/base": "^3.1.0",
"codeception/specify": "~1.2.0",
"codeception/verify": "~1.2.0",
"phpunit/phpunit": "~8.5.2"
}
}
Also, note that I have specified the vehicles namespace and the source directory to load the interfaces and classes. Now install the dependencies using the command as shown below.
# Execute from the project root directory
composer update
# Update the autoloader
composer dumpautoload -o
It will create the vendor directory to store the project dependencies and the autoloader script. It will also generate the composer.lock to keep track of the project dependencies installed for the project.
Update Interfaces
In this step, we will update the interfaces to design the vehicle system. I have updated all the three interfaces as shown below.
IVehicle
Note that I have used the keyword namespace to specify the namespace of the interface IVehicle.
<?php
namespace vehicles\design;
interface IVehicle {
public function getId() : int;
public function setId(int $id);
public function getName() : string;
public function setName( string $name);
}
ICar
<?php
namespace vehicles\design;
interface ICar extends IVehicle {
public function getMaxPassengers() : int;
public function setMaxPassengers(int $maxPassengers);
}
ITruck
<?php
namespace vehicles\design;
interface ITruck extends IVehicle {
public function getMaxLoad() : float;
public function setMaxLoad(float $maxLoad);
}
Update Classes
In this step, we will update the classes of the vehicle system. I have updated all the three classes as shown below.
Vehicle
Note that I have used the keyword namespace to specify the namespace of the class Vehicle.
<?php
namespace vehicles\impl;
use vehicles\design\IVehicle;
abstract class Vehicle implements IVehicle {
protected $id;
protected $name;
public function getId() : int {
return $this->id;
}
public function setId(int $id) {
$this->id = $id;
}
public function getName() : string {
return $this->name;
}
public function setName( string $name) {
$this->name = $name;
}
}
Car
<?php
namespace vehicles\impl;
use vehicles\design\ICar;
class Car extends Vehicle implements ICar {
protected $maxPassengers;
public function getMaxPassengers() : int {
return $this->maxPassengers;
}
public function setMaxPassengers(int $maxPassengers) {
$this->maxPassengers = $maxPassengers;
}
}
Truck
<?php
namespace vehicles\impl;
use vehicles\design\ITruck;
class Truck extends Vehicle implements ITruck {
protected $maxLoad;
public function getMaxLoad() : float {
return $this->maxLoad;
}
public function setMaxLoad(float $maxLoad) {
$this->maxLoad = $maxLoad;
}
}
Autoloading
Here comes the interesting part after defining and declaring the interfaces and classes. Update the autoloader using the command as shown below.
# Update the autoloader
composer dumpautoload -o
Now update the index.php file as shown below.
<?php
require __DIR__ . "\../vendor/autoload.php";
use vehicles\impl\Car;
use vehicles\impl\Truck;
$car = new Car();
$car->setId(1231234);
$car->setName('Renault Triber');
$car->setMaxPassengers(7);
$truck = new Truck();
$truck->setId(1090231);
$truck->setName('Toyota Tundra');
$truck->setMaxLoad(910);
?>
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Vehicles - Autoloading Demo</title>
</head>
<body>
<h1>Car Details</h1>
<table>
<tr><td>Id</td><td><?= $car->getId() ?></td></tr>
<tr><td>Name</td><td><?= $car->getName() ?></td></tr>
<tr><td>Max Passengers</td><td><?= $car->getMaxPassengers() ?></td></tr>
</table>
<h1>Truck Details</h1>
<table>
<tr><td>Id</td><td><?= $truck->getId() ?></td></tr>
<tr><td>Name</td><td><?= $truck->getName() ?></td></tr>
<tr><td>Max Load</td><td><?= $truck->getMaxLoad() ?></td></tr>
</table>
</body>
</html>
I have included the autoload.php file as the first line of index.php. This will make sure that our interfaces and classes get loaded. Also, note that I have used the keyword use to import the classes required in index.php instead of using require or include.
Summary
This tutorial explained the autoloading of the project interfaces and classes using Composer with example code. The code used in this tutorial is also available at GitHub. You are most welcome to join the discussion on autoloading by adding your comments either directly to Tutorials24x7 or via Disqus.