hnqca/router-php

一个轻量级且直观的PHP路由库,支持MVC模式、中间件、RESTful动词(GET、POST、PUT、PATCH和DELETE)、路径参数和查询参数。

v1.0.0 2024-04-05 12:25 UTC

This package is auto-updated.

Last update: 2024-09-05 13:22:53 UTC


README

支持MVC模式、中间件、常见的RESTful动词(GET、POST、PUT、PATCH和DELETE),方便处理URL参数和查询。简化了创建友好的URL和RESTful API的过程。

安装

通过 composer

composer require hnqca/router-php

示例

在 "example" 目录中,您可以找到一些示例代码,演示如何使用这个库。

配置

为了确保路由正确运行,需要将所有流量重定向到主路由文件(index.php)。

以下是对Apache和Nginx进行重定向所需的配置。

Apache (.htaccess)

RewriteEngine On
Options All -Indexes

## WWW Redirect.
# RewriteCond %{HTTP_HOST} !^www\. [NC]
# RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

## HTTPS Redirect
# RewriteCond %{HTTP:X-Forwarded-Proto} !https
# RewriteCond %{HTTPS} off
# RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# URL Rewrite
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php?uri=/$1 [L,QSA]

Nginx

location / {
  if ($script_filename !~ "-f"){
    rewrite ^(.*)$ /index.php?uri=/$1 break;
  }
}

路由示例(index.php)

<?php

require_once dirname(__DIR__, 1) . '/vendor/autoload.php';

use Hnqca\Router\Router;
use Hnqca\Router\Request;
use Hnqca\Router\Response;

/**
 * Examples of Middleware classes
 */
require_once __DIR__ . '/Middlewares/AuthMiddleware.php';

use Middlewares\AuthMiddleware;

/**
 * Examples of Controller classes
 */
require_once __DIR__ . '/Controllers/HomeController.php';
require_once __DIR__ . '/Controllers/ProductController.php';
require_once __DIR__ . '/Controllers/UserController.php';
require_once __DIR__ . '/Controllers/AdminController.php';
require_once __DIR__ . '/Controllers/ErrorController.php';

use Controllers\HomeController;
use Controllers\ProductController;
use Controllers\UserController;
use Controllers\AdminController;
use Controllers\ErrorController;

/**
 * Routes
 */
$route = new Router();

$route->get('/',         [HomeController::class,     'index']);
$route->get("/products", [ProductController::class,  'index']);


/**
 * Route without a controller class
 */
$route->get('/hello/{name}', [], function(Request $req, Response $res){

    $name = $req->getParams()->name;
    
    return $res->send(200, "Hello, {$name}!");
});

/**
 * Route with middleware
 */
$route->get('/admin', [AdminController::class, 'index'], function () {
    return (new AuthMiddleware)->onlyAdmin();
});


/**
 * Example of routes for CRUD operations
 */
$route->post("/users",        [UserController::class,  'create']);
$route->get("/users",         [UserController::class,  'index']);
$route->get("/users/{id}",    [UserController::class,  'show']);
$route->put("/users/{id}",    [UserController::class,  'update']);
$route->patch("/users/{id}",  [UserController::class,  'update']);
$route->delete("/users/{id}", [UserController::class,  'delete']);


/**
 * Execute
 */
$route->dispatch();


/**
 * Example for error handling in the route
 * 404 Not Found, 405 Method Not Allowed and 501 Not Implemented
 */
if ($route->error()) {
    return (new ErrorController)->show($route->error());
}

路径参数

index.php:

$route->get("/users/{id}", [UserController::class, 'show']);

UserController.php:

class UserController
{
    public function show(Request $req, Response $res)
    {
        // var_dump($req->getParams());

        $userId = $req->getParams()->id;

        if (!filter_var($userId, FILTER_VALIDATE_INT)) {
            return $res->send(400, "It is expected to receive a value of integer type.");
        }
        
        return $res->send(200, "Viewing user data with ID: {$userId}");
    }
}

示例

查询参数

index.php:

$route->get("/products", [ProductControllers::class, 'index']);

ProductController.php:

class ProductController
{
    public function index(Request $req, Response $res)
    {
        $filter = $req->getQuery()->filter ?? null;

        if ($filter) {
            return $res->send(200, "Filtering products by {$filter}"); 
        }

        return $res->send(200, "Listing all products..."); 
    }
}

示例