PHP
Summary - Composer
Set up a project with managed dependencies using composer.json, require and autoload.
Summary - Composer
In this group you learned what Composer is, the structure of the config file, adding packages with require, PSR-4 autoload, installing packages from Packagist, and the install/update difference. Now you will combine them to build a small project with managed dependencies: define the config and use a class through the autoload.
A project skeleton with managed dependencies
In a Composer project, you first write the config file; required packages go into require, namespace mappings go into autoload psr-4. composer install installs packages and produces vendor/autoload.php.
At the top of the code, require_once vendor/autoload.php is called; afterwards every class imported with use loads automatically.
Exercise Config + autoload + class usage
Define namespace App;; inside it add an Application class. Add a public string $name property and a public function __construct() that assigns $this->name = "shop". public function name(): string should return $this->name.
Then define $config = ["name" => "app/shop", "autoload" => ["psr-4" => ["App\\" => "src/"]]]. Create an instance with $app = new \App\Application() and print the $app->name value. Finally print the autoload psr-4 mapping in the form App\ => src/.
Show example solution
string { return $this->name; } }. Write $config = ["name" => "app/shop", "autoload" => ["psr-4" => ["App\\" => "src/"]]];. Print the property with $app = new \App\Application(); echo $app->name . "\n";. Print the mapping with foreach ($config["autoload"]["psr-4"] as $ns => $path) { echo $ns . " => " . $path . "\n"; }.
Example solution:
<?php
namespace App;
class Application {
public string $name;
public function __construct() {
$this->name = "shop";
}
public function name(): string {
return $this->name;
}
}
$config = ["name" => "app/shop", "autoload" => ["psr-4" => ["App\\" => "src/"]]];
$app = new \App\Application();
echo $app->name . "\n";
foreach ($config["autoload"]["psr-4"] as $ns => $path) {
echo $ns . " => " . $path . "\n";
}
Exercise PSR-4 classmap builder
Mimic the classmap that composer dump-autoload produces. Write a buildClassmap(array $classes, array $map): array function: for each class in $classes, iterate $map; check strpos against 0, strip the matching prefix with substr, turn the remaining \ into / with str_replace, prepend base and append .php; store the result as $classmap[$class].
Define $map = ["App\\" => "src/"] and $classes = ["App\\Models\\User", "App\\Services\\Auth"]. Build the classmap and print each line as App\Models\User => src/Models/User.php.
Show example solution
array { $classmap = []; foreach ($classes as $class) { foreach ($map as $prefix => $base) { if (strpos($class, $prefix) === 0) { $relative = substr($class, strlen($prefix)); $relative = str_replace("\\", "/", $relative); $classmap[$class] = $base . $relative . ".php"; break; } } } return $classmap; }. Define $map = ["App\\" => "src/"]; $classes = ["App\\Models\\User", "App\\Services\\Auth"];. Print with $classmap = buildClassmap($classes, $map); foreach ($classmap as $class => $file) { echo $class . " => " . $file . "\n"; }.
Example solution:
<?php
function buildClassmap(array $classes, array $map): array {
$classmap = [];
foreach ($classes as $class) {
foreach ($map as $prefix => $base) {
if (strpos($class, $prefix) === 0) {
$relative = substr($class, strlen($prefix));
$relative = str_replace("\\", "/", $relative);
$classmap[$class] = $base . $relative . ".php";
break;
}
}
}
return $classmap;
}
$map = ["App\\" => "src/"];
$classes = ["App\\Models\\User", "App\\Services\\Auth"];
$classmap = buildClassmap($classes, $map);
foreach ($classmap as $class => $file) {
echo $class . " => " . $file . "\n";
}
Test yourself
-
What does the config file define?
- Only the package name
- Dependencies and autoload
- Database connection password
- Browser HTTP headers
Show answer
Dependencies and autoload — Correct. The config file carries require and autoload.
Next lesson: Matching with preg_match()