Author - StudySection Post Views - 49 views
PHP

Chain of Responsibility in PHP

A chain of responsibility is a behavioral design pattern that allows a request to pass through a chain of potential employees until the request is fulfilled.

This pattern allows you to resolve requests without connecting the sender class to a specific receiver class. The runtime chain can be dynamically configured with any processor that follows the standard processor interface.

Use of patterns in PHP

Usage example: Chain of responsibility is very common in various PHP frameworks. Arguably, one of the most popular examples of using this pattern in PHP is the HTTP Request Middleware described in PSR-15.

Identity: This pattern is characterized by the behavior of a group of objects that indirectly call the same methods on other objects, while all objects follow a common interface.

Example
The most common use of chain of responsibility (CoR) in the PHP world is found in HTTP request middleware. This is implemented by the most popular PHP frameworks and even standardized as part of PSR-15.

Here’s how it works: HTTP requests must go through middleware for application processing. Each middleware can refuse further processing of the request or forward it to the next middleware. After the request has successfully passed through all the middleware, the main processor of the application can finally complete it.

You can see that this approach is counter to the original intent of the pattern. Indeed, in a typical implementation, the request is passed down the chain only if the current processor cannot handle it, while the middleware passes the request down the chain if it thinks that the application can handle the request. However, since middleware objects are chained, the whole concept is still considered an instance of the CoR pattern.
<?php
namespace Webner\COR\RW;
/**
* The classic CoR pattern is a single role for the objects that compose a
* chain of operations.
*
* The base Middleware class declares an interface for middleware binding
* something in a chain.
*/
abstract class CorMiddleware
{
/**
* @var CorMiddleware
*/
private $next;
/**
* This method is use to build a cor of middleware objects.
*/
public function linkedWith(CorMiddleware $next): CorMiddleware
{
$this->next = $next;
return $next;
}
public function checked(string $username, string $password): bool
{
if (!$this->next) {
return true;
}
return $this->next->checked($username, $password);
}
}
/**
* Middleware checks whether a user with given credentials is exist or not.
*/
class UserVerifyMiddleware extends CorMiddleware
{
private $server;
public function __construct(Server $server)
{
$this->server = $server;
}
public function checked(string $username, string $password): bool
{
if (!$this->server->hasEmail($username)) {
echo "User verify Middleware==== This user is not registered! Please registered\n";
return false;
}
if (!$this->server->isValidPassword($username, $password)) {
echo "User verify Middleware==== Wrong is password! Please try again!\n";
return false;
}
return parent::checked($username, $password);
}
}
/**
* This Middleware checks whether a user associated with the request
* has sufficient permissions.
*/
class Role_Checked_Middleware extends CorMiddleware
{
public function checked(string $username, string $password): bool
{
if ($username === "gopi.chand@webners.com") {
echo "Welcome Admin!\n";
return true;
}
echo "Hello, user!\n";
return parent::checked($username, $password);
}
}
/**
* Middleware checks whether there are too many failed login
* requests.
*/
class Throttling_Middleware extends CorMiddleware
{
private $request_Per_Minute;
private $request;
private $current_Time;
public function __construct(int $request_Per_Minute)
{
$this->request_Per_Minute = $request_Per_Minute;
$this->current_Time = time();
}
public function checked(string $username, string $password): bool
{
if (time() > $this->current_Time + 60) {
$this->request = 0;
$this->current_Time = time();
}
$this->request++;
if ($this->request > $this->request_Per_Minute) {
echo "You have exceed the limit. Please try again later!\n";
die();
}
return parent::checked($username, $password);
}
}
class Server
{
private $users = [];
/**
* @var CorMiddleware
*/
private $middleware;
public function setMiddleware(CorMiddleware $middleware): void
{
$this->middleware = $middleware;
}
public function loggin(string $username, string $password): bool
{
if ($this->middleware->checked($username, $password)) {
echo "Server: Authorization has been successful!\n";
// Do something useful for authorized users.
return true;
}
return false;
}
public function registeration(string $username, string $password): void
{
$this->users[$username] = $password;
}
public function hasEmail(string $username): bool
{
return isset($this->users[$username]);
}
public function isValidPassword(string $username, string $password): bool
{
return $this->users[$username] === $password;
}
}
/**
* The client code.
*/
$server = new Server();
$server->registeration("gopi.chand@webners.com", "admin1234@");
$server->registeration("webnerstest@webners.com", "123456");
$middleware = new Throttling_Middleware(2);
$middleware
->linkedWith(new UserVerifyMiddleware($server))
->linkedWith(new Role_Checked_Middleware());
$server->setMiddleware($middleware);
do {
echo "\n Please Enter Your Username:\n";
$username = readline();
echo "Enter your password:\n";
$password = readline();
$success = $server->loggin($username, $password);
} while (!$success);

php1
php2

Study Section provides a big list of certification exams through its online platform. The French Certification Exam can help you to certify your skills to communicate in the French language. Whether you are new to the language or you are an expert in it, this French certification exam can test the ability of anybody’s command over the French language.

Leave a Reply

Your email address will not be published.