this Pre-controller Is a design pattern for centralized request processing in web application development. All requests are routed through a single central controller, which directs them to the appropriate component or module, rather than having multiple entry points for different parts of the system.
how it works
-
Single entry point: All HTTP requests are redirected to a single file (usually
index.php
) using a web server configuration (e.g.,.htaccess
for routing rules in Apache or Nginx). - routing: The front-end controller parses the URL and determines which part of the code should be executed. This can be implemented manually or using a routing library/framework.
- delegation: Based on the route, the front-end controller delegates the request to the appropriate controller (class or method), which processes the data and sends back the response.
- reply: The controller generates a response (usually HTML or JSON) that is sent back to the browser or client.
advantage
- centralization: All incoming application flows go through a single point of processing, making it easier to manage and track requests.
- flexibility: Easily integrate domain-wide functionality such as authentication, permission control, logging or error handling.
- Reusability: Common logic can be centralized in the front-end controller, reducing duplication.
- Maintainability: Centralization simplifies updates, such as adding new routes or controllers.
example
Directory structure
/app
/Controllers
HomeController.php
ProductController.php
/Core
Entrypoint.php
/config
routes.php
/public
index.php
/vendor
composer.json
autoload
To implement PSR-4, create a composer.json file in the project root directory:
{
"autoload": {
"psr-4": {
"App\\": "app/"
}
}
}
Execute the following command to generate the autoloader:
composer dump-autoload
redirect request
Apache(.htaccess
)
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
nginx
server {
listen 80;
server_name example.com;
root /path/to/your/project/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; # Adjust for your PHP version
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(css|js|jpg|jpeg|png|gif|ico|woff|woff2|ttf|svg|eot|ttc|otf|webp|avif)$ {
expires max;
log_not_found off;
}
location ~ /\.ht {
deny all;
}
}
After saving the configuration file, restart Nginx to apply the changes
sudo systemctl reload nginx
controller
HomeController
namespace App\Controllers;
class HomeController {
public function index(): void {
echo "Welcome to the home page!";
}
}
ProductController
namespace App\Controllers;
class ProductController
{
public function list(): void
{
echo "Product list.";
}
}
nuclear
Entrypoint
namespace App\Core;
class Entrypoint {
public function __construct(private array $routes) {
}
public function handleRequest(): void {
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
if (isset($this->routes[$uri])) {
$route = $this->routes[$uri];
$controller = new $route['controller'];
$method = $route['method'];
if (method_exists($controller, $method)) {
$controller->$method();
} else {
$this->sendResponse(500, "Method not found.");
}
} else {
$this->sendResponse(404, "Page not found.");
}
}
private function sendResponse(int $statusCode, string $message): void {
http_response_code($statusCode);
echo $message;
}
}
Configuration
routes
$routes = [
"https://dev.to/" => [
'controller' => 'HomeController',
'method' => 'index'
],
'/products' => [
'controller' => 'ProductController',
'method' => 'list'
]
];
Index (front controller)
require_once __DIR__ . '/../vendor/autoload.php';
use App\Core\Entrypoint;
$routes = require __DIR__ . '/../config/routes.php';
$entrypoint = new Entrypoint($routes);
$entrypoint->handleRequest();
result
This implementation:
- Use centralized request processing Pre-controller pattern.
- Encapsulate routing logic in
Entrypoint
class. - use PSR-4 For autoloading and better code organization.
- Use Nginx settings for seamless setup.