PHP - Namespace, Autoloader, Message Handler, and ORM
Translated from German using ChatGPT.
Date: November 2021
Reading time: 3 minutes
My last blog post was about PHP basics. Now I will write in more detail about four other topics:
- Namespace
- autoloader
- Message Handler
- Object Relational Mapper (ORM)
Namespace
Namespaces offer two significant advantages:
- Elements (classes, functions and constants) can have the same name.
- Code can be divided into logical groups.
No collisions
occur with the help of namespaces
.
Usage
To make use of the advantages of namespaces
, you must use the namespace
keyword.
<?php
namespace Data;
class Database {
public function __construct() {
echo "Fully qualified class name: ".__CLASS__."\n";
}
}
?>
After you have integrated the class with use
, you can use it.
<?php
use Data\Database;
require "Database.php";
$db = new Database();
?>
Autoloader
In the example above, you can see that the classes you want to use must be included. However, manual inclusion has two
problems:
- Expense - if you have a lot of classes, including them takes a lot of time.
- Error-proneness - if you move a class, you have to adjust the path.
An autoloader
solves these problems by searching for the corresponding files and integrating them correctly.
function autoload($className) {
$className = ltrim('classes/' . $className, '\\');
$fileName = '';
$namespace = '';
if ($lastNsPos = strrpos($className, '\\')) {
$namespace = substr($className, 0, $lastNsPos);
$className = substr($className, $lastNsPos + 1);
$fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
}
$fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
require $fileName;
}
spl_autoload_register('autoload');
Here, line 2 defines that the classes are located in the classes
folder.
Message Handler
In my web application, the user can edit data. They should receive feedback when saving.
However, my initial approach had two problems:
- No messages could be collected.
- Filtering by status or color display in the frontend was not possible.
Therefore I implemented a message handler
.
Message class
The Message
class stores status and message.
<?php
namespace MessageHandler;
class Message {
private string $message;
private string $status;
public const SUCCESS = "success";
public const WARNING = "warning";
public const ERROR = "error";
public function __construct(string $message, string $status) {
$this->message = $message;
$this->status = $status;
}
public function getMessage(): string {
return $this->message;
}
public function getStatus(): string {
return $this->status;
}
}
?>
MessageHandler class
The MessageHandler
manages messages and stores them in an array.
<?php
namespace MessageHandler;
class MessageHandler {
private array $messages = [];
public function getMessages(): array {
return $this->messages;
}
public function getErrorMessages(): array {
return array_filter($this->messages, fn($m) => $m->getStatus() == Message::ERROR);
}
public function getWarningMessages(): array {
return array_filter($this->messages, fn($m) => $m->getStatus() == Message::WARNING);
}
public function getSuccessMessages(): array {
return array_filter($this->messages, fn($m) => $m->getStatus() == Message::SUCCESS);
}
public function addMessage(string $message, string $status): void {
$this->messages[] = new Message($message, $status);
}
}
?>
Certain messages can be retrieved on request.
<?php foreach ($messageHandler->getSuccessMessages() as $message): ?>
<p style="font-size: 20px; color: mediumseagreen;"><?= $message->getMessage(); ?></p>
<?php endforeach; ?>
Object Relational Mapper (ORM)
ORM stores data from the database in objects (mapping
). CRUD operations can then be performed on these objects.
Example
In my project I have created a Database
class.
Connect
If you want to use the MySQL database, you can call the connect
method.
public function connect() {
$this->mysqli = new mysqli("localhost", "root", "root", "apparel");
}
Disconnect
The disconnect
function must also be called to disconnect the connection.
public function disconnect() {
$this->mysqli->close();
}
CRUD
The ORM class can also be used to handle CRUD operations.
In this example, you get the desired artists from the database.
public function getArtists($ids = null): array {
$artistList = [];
$query = "SELECT * FROM artist" . ($ids ? " WHERE artist_id IN ($ids)" : "");
$artistResponse = $this->mysqli->query($query);
while ($row = $artistResponse->fetch_assoc()) {
$artistList[] = new Artist($row["type"], $row["name"], $row["age"], $row["residence"], $row["nationality"], $row["artist_id"]);
}
return $artistList;
}
A fire is extinguished here.
public function deleteBrand(Brand $brand) {
$id = $brand->getId();
$stmt = $this->mysqli->prepare("DELETE FROM brand WHERE brand_id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
}
On line 4, bind_param
is used to insert the $id
into the SQL syntax so that it can then be executed.