alexoliverwd/basic-router 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

alexoliverwd/basic-router

Composer 安装命令:

composer require alexoliverwd/basic-router

包简介

A minimalistic yet powerful PHP class designed to handle routing in web applications.

README 文档

README

PHPUnit Latest Stable Version License

Router

This application is a minimalistic yet powerful PHP class designed to handle routing in web applications. It's a dependency-free solution that offers a straightforward approach to mapping HTTP requests to functions or methods, with full support for registering routes and middleware using PHP Attributes.

Important

To prevent XSS attacks, use the built-in getParameter method when retrieving values from query parameters.

For more information on using the getParameter method, see the XSS Prevention section.

Installation

Preferred installation is via Composer:

composer require alexoliverwd/basic-router

Usage

When a request comes in to the application, the Router instance will examine the request method (GET, POST, PUT, DELETE) and the requested URL. If a matching route is found, the associated callback function will be executed.

Attribute-Based Controller Routing

Attributes provide a modern, native way to declare route metadata directly in your code. This approach is now recommended for defining routes, while conventional methods will remain supported for compatibility.

use AOWD\Router;
use AOWD\Attributes\Route;
use AOWD\Attributes\GET;
use AOWD\Attributes\PUT;
use AOWD\Attributes\POST;
use AOWD\Attributes\DELETE;

class myRoutes {
    #[Route('/hello-world', 'get')]
    public function homeGet(): void
    {
        echo "GET - Hello World";
    }

    #[Route('/hello-world/segment/[0-9]+', 'get')]
    public function homeGetSegment(Router $router): void
    {
        echo $router->getSegment(1);
    }

    #[Route('/hello-world', 'post')]
    public function homePost(): void
    {
        echo "POST - Hello World";
    }

    #[Route('/users/{userId}/orders/{orderId}', 'get')]
    public function getUserOrder(Router $router): void
    {
        $user_id = $router->URLAttribute("userId");
        $order_id = $router->URLAttribute("orderId");
        echo "User: $user_id Order: $order_id";
    }
    
    // CRUD Attributes

    #[GET('/crud-hello-world')]
    public function crudHomeGet(): void
    {
        echo "CRUD GET - Hello World";
    }

    #[PUT('/crud-hello-world')]
    public function crudHomePut(): void
    {
        echo "CRUD PUT - Hello World";
    }

    #[POST('/crud-hello-world')]
    public function crudHomePost(): void
    {
        echo "CRUD POST - Hello World";
    }

    #[DELETE('/crud-hello-world')]
    public function crudHomeDelete(): void
    {
        echo "CRUD DELETE - Hello World";
    }
}

$router = new Router();
$router->registerRouteController(new myRoutes());
$router->run();

Route Interface

Classes that implement the route interface have access to the prepend_path variable. This variable allows all routes registered within the class to be automatically prefixed with a common path.

This is useful when all routes in a class must follow a shared convention, such as starting with /api/. If the convention needs to change in the future, it can be updated in one place at the top level rather than modifying every individual route definition within the class.

use AOWD\Interfaces\Route as RouteInterface;
use AOWD\Attributes\Route;
use AOWD\Attributes\GET;
use AOWD\Router;

class routeWithPrependedSlug implements RouteInterface
{
    public string $prepend_path;
    public function __construct() {
        $this->prepend_path = $_ENV['PAGE_WITH_SLUG'];
    }

    #[Route('-env', 'get')]
    public function pageWithEnv(): void
    {
        echo "Page with ENV";
    }

    #[GET('-crud-hello-world')]
    public function homeCrudGET(): void
    {
        echo "CRUD GET - Hello World";
    }
}

$router = new Router();
$router->registerRouteController(new routeWithPrependedSlug());
$router->run();

Registering Multiple Controllers

In the below example, multiple controllers can be registered with the router in a single call using the registerRouteController() method. Each controller class defines its own set of routes through PHP attributes, the router will automatically scan and map them.

use AOWD\Router;
use AOWD\Attributes\Route;

class getRoutes {
    #[Route('/hello-world', 'get')]
    public function homeGet(): void
    {
        echo "GET - Hello World";
    }

    #[Route('/hello-world/segment/[0-9]+', 'get')]
    public function homeGetSegment(Router $router): void
    {
        echo $router->getSegment(1);
    }
}

class postRoutes {
    #[Route('/hello-world', 'post')]
    public function homePost(): void
    {
        echo "POST - Hello World";
    }
}

$router = new Router();
$router->registerRouteController(new getRoutes(), new postRoutes());
$router->run();

Conventional Method

use AOWD\Router;

$router = new Router();

$router->register('GET', '/', function () {
    echo 'get';
});

$router->register("get", "/second/segment/[0-9]+", function () use ($router) {
    echo $router->getSegment(1);
});

// CRUD Helper Methods

$router->get('/', function () {
    echo 'get';
});

$router->put('/', function () {
    echo 'put';
});

$router->post('/', function () {
    echo 'post';
});

$router->delete('/', function () {
    echo 'delete';
});

$router->run();

In this example, if a GET request is made to the root URL (/), the function function () { echo 'get'; } will be called, and the string "get" will be output.

Registering an endpoint

The register method registers a new route in the routing system.

Parameters

  1. Method: The HTTP method (e.g., GET, POST, PUT, DELETE).
  2. Route: The URL pattern for the route.
  3. Callback: The callable function or method to be executed when the route is matched.

Return Value:

  • true: If the route is successfully registered.
  • false: If the route already exists for the specified method.

Executing registered routes

The run() method is the core of the routing system. It's responsible for:

  1. Parsing the Request: Extracts the requested URL path and HTTP method from the server environment.
  2. Matching Routes: Compares the parsed request against registered routes to find a matching route.
  3. Executing Callback: If a match is found, the associated callback function is executed.
  4. Handling 404 Errors: If no match is found, the registered 404 error handler is invoked.

Unregistering an endpoint

$router->unregister('get', '/get');

This method unregisters a previously registered route from the routing system.

Parameters

  1. Method: The HTTP method (e.g., GET, POST, PUT, DELETE) in lowercase.
  2. Route: The URL pattern of the route to be unregistered.

Return Value:

  • true: If the route is successfully unregistered.
  • false: If the route doesn't exist or couldn't be unregistered.

Handling 404 errors

$router->register404(function () {
    echo '404 error';
});

The register404 method registers a callback function to be executed when a 404 Not Found error occurs. This allows you to customize the error handling behavior for your application.

Parameters

  1. Callback: A callable function or method that will be invoked when a 404 error is encountered. This callback can be used to generate custom error messages, redirect to a specific page, or perform other error handling actions.

Returning values from URL segments

The getSegment method returns a single segment value from a URI. The returned value may be an integer or a string, depending on how the segment is referenced. The method accepts either an integer index or a string key.

Using an integer index

When an integer is provided, it represents the position of the segment in the URI, counted from left to right, starting at 0.

For example, given the URI: segment/standard/123

  • getSegment(0) returns segment
  • getSegment(1) returns standard
  • getSegment(2) returns 123

Negative integers are also supported and count segments from right to left:

  • getSegment(-1) returns 123
  • getSegment(-2) returns standard

Using a string key

When a string is provided, getSegment returns the value associated with a URI template attribute.

For example, given the URI template: segment/standard/{id} Calling: getSegment('id') returns: 123

use AOWD\Router;

$router = new Router();

$router->register("get", "/segment/standard/{id}", function () use ($router) {
    echo $router->getSegment('id');
});

$router->run();

For more information about URI template attributes, see the next section.

Returning values from URL attributes

When defining a route that includes attribute placeholders (e.g., /users/{userId}/orders/{orderId}), you can easily retrieve those values by using the URLAttribute method.

#[Route('/users/{userId}/orders/{orderId}', 'get')]
public function URLAttributesTest(Router $router): void
{
    $user_id = $router->URLAttribute("userId");
    $order_id = $router->URLAttribute("orderId");
    echo "User: $user_id Order: $order_id";
}

#[Route('/segment/attribute/{id}', 'get')]
public function homeGetSegmentIdViaAttribute(Router $router): void
{
	echo $router->getSegment('id');
}

Parameters

  1. Reference ID (string) — The name of the URL attribute to retrieve (e.g., userId).
  2. Fallback (string|int, optional) — A value to return if the requested attribute is not found.

Note

Attribute names may only contain alphabetic characters (A–Z, a–z), hyphens, and underscores (i.e., a-z, A-Z, -, _).

XSS Prevention

Get safe values from query string parameters

To mitigate the risk of cross-site scripting (XSS) attacks, use the built-in getParameter method. This method retrieves a sanitised scalar value from a query string parameter, helping prevent the injection of malicious scripts.

use AOWD\Router;

$router = new Router();

// URL: localhost://xss?q=<script>alert('XSS')</script>
$router->register("get", "/xss", function () use ($router) {
	// Will display &lt;script&gt;alert(&#039;XSS&#039;)&lt;/script&gt;
    echo $router->getParameter('q');
});

$router->run();

Middleware

Middleware in this routing API provides a way to intercept and process requests before they reach your route handler. This allows you to implement reusable logic such as authentication, logging, CORS handling, rate limiting, or response modification without duplicating code inside your route controllers.

Middleware classes must implement or extend the AOWD\Interfaces\Middleware interface, which requires a handle() method. When a route is matched, any attached middleware will be executed in the order they are defined.

Usage

1. Creating a Middleware

To create a middleware, implement the MiddlewareInterface and define the handle() method.

use AOWD\Interfaces\Middleware as MiddlewareInterface;

class helloWorld implements MiddlewareInterface
{
    public function handle(): void
    {
        echo "Hello World ";
    }
}

This simple example outputs Hello World before the route logic executes.

2. Attaching Middleware to a Route

Middleware can be attached to a route using the #[Middleware()] attribute.

use AOWD\Attributes\Route;
use AOWD\Attributes\Middleware;

class myRoutes {
    #[Route('/hello-world-middleware', 'get')]
    #[Middleware(helloWorld::class)]
    public function homeGetMiddleware(): void
    {
        echo "GET";
    }
}

In this example:

  • A GET request to /hello-world-middleware will first run the helloWorld middleware.
  • The middleware prints "Hello World ".
  • Then the route handler executes and prints "GET".
  • The final response is:
Hello World GET

3. Registering Routes and Running the Router

After defining routes and middleware, register your route controller with the Router and start it:

use AOWD\Router;

$router = new Router();
$router->registerRouteController(new myRoutes());
$router->run();

Full Example

Here’s everything combined into a single working example:

use AOWD\Router;
use AOWD\Attributes\Route;
use AOWD\Attributes\Middleware;
use AOWD\Interfaces\Middleware as MiddlewareInterface;

class helloWorld implements MiddlewareInterface
{
    public function handle(): void
    {
        echo "Hello World ";
    }
}

class myRoutes {
    #[Route('/hello-world-middleware', 'get')]
    #[Middleware(helloWorld::class)]
    public function homeGetMiddleware(): void
    {
        echo "GET";
    }
}

$router = new Router();
$router->registerRouteController(new myRoutes());
$router->run();

alexoliverwd/basic-router 适用场景与选型建议

alexoliverwd/basic-router 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 418 次下载、GitHub Stars 达 0, 最近一次更新时间为 2024 年 12 月 08 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「routing」 「http」 「crud」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 alexoliverwd/basic-router 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 alexoliverwd/basic-router 我们能提供哪些服务?
定制开发 / 二次开发

基于 alexoliverwd/basic-router 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 418
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 15
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2024-12-08