mathsgod/light-server 问题修复 & 功能扩展

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

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

mathsgod/light-server

Composer 安装命令:

composer require mathsgod/light-server

包简介

A lightweight PHP 8.1+ file-based routing server inspired by Nuxt.js pages, built on PSR-7/PSR-15 with League Route and Laminas.

README 文档

README

Tests

A lightweight PHP 8.1+ web framework with file-based routing, PSR-7 support, and automatic dependency injection.

Requirements

  • PHP 8.1+

Features

  • 📄 File-system based routing — drop a file in pages/, get a route automatically
  • 🔀 Dynamic routespages/blog/{id}/index.php/blog/{id}
  • 🛠️ PSR-7 / PSR-15 standard — standard HTTP message and middleware interfaces
  • 💉 Automatic dependency injection — method parameters resolved from a PSR-11 container
  • 🎯 Attribute-based middleware — attach PSR-15 middleware directly to handler methods via PHP attributes
  • 💪 Global middleware — pipe middleware at the server level
  • 🔒 Built-in security headers — optional SecurityHeadersMiddleware

Installation

composer require mathsgod/light-server

Quick Start

1. Create an entry point

<?php
// public/index.php

require 'vendor/autoload.php';

(new Light\Server())->run();

2. Create a page handler

<?php
// pages/index.php

use Laminas\Diactoros\Response\TextResponse;

return new class {
    public function get(): TextResponse
    {
        return new TextResponse("Hello, World!");
    }

    public function post(): TextResponse
    {
        return new TextResponse("POST request received");
    }
};

Routing

Routes are generated automatically from the pages/ directory structure:

File Route
pages/index.php /
pages/about.php /about
pages/blog/index.php /blog/
pages/blog/{id}/index.php /blog/{id}

If the pages/ directory does not exist, the server starts normally with no routes.

HTTP Methods

Define public methods matching the HTTP verb (case-insensitive):

return new class {
    public function get(): ResponseInterface { }
    public function post(): ResponseInterface { }
    public function put(): ResponseInterface { }
    public function delete(): ResponseInterface { }
    public function patch(): ResponseInterface { }
};

Dynamic Routes

Route parameters are available via $request->getAttribute():

<?php
// pages/blog/{id}/index.php

use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ServerRequestInterface;

return new class {
    public function get(ServerRequestInterface $request): JsonResponse
    {
        $id = $request->getAttribute('id');
        return new JsonResponse(['id' => $id]);
    }
};

Route Constraints

Since routing is powered by League\Route, you can constrain route parameters directly in the folder/file name using {param:type} syntax:

Constraint Pattern Example match
{id:number} [0-9]+ 123
{name:word} [a-zA-Z]+ raymond
{slug:slug} [a-z0-9-]+ my-post
{token:alphanum_dash} [a-zA-Z0-9-_]+ abc-123_x
{id:uuid} UUID format 550e8400-e29b-41d4-a716-446655440000
{path:any} .+ foo/bar/baz

Example: Only match when id is numeric and name is alphabetic:

pages/
└── user/
    └── {id:number}/
        └── {name:word}/
            └── index.php   →   /user/{id:number}/{name:word}/
/user/1/raymond/   ✅  matches  (id=1, name=raymond)
/user/test/raymond/ ❌  no match (id is not numeric)
<?php
// pages/user/{id:number}/{name:word}/index.php

use Laminas\Diactoros\Response\TextResponse;
use Psr\Http\Message\ServerRequestInterface;

return new class {
    public function get(ServerRequestInterface $request): TextResponse
    {
        $id   = $request->getAttribute('id');
        $name = $request->getAttribute('name');
        return new TextResponse("User ID: $id, Name: $name");
    }
};

Dependency Injection

Method parameters are resolved automatically by type hint:

  • ServerRequestInterface — injects the current HTTP request
  • Any other type hint — resolved from the PSR-11 container (if provided)
  • Unresolvable parameters — receive null
<?php
// pages/users.php

use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ServerRequestInterface;

return new class {
    public function get(ServerRequestInterface $request, UserRepository $repo): JsonResponse
    {
        return new JsonResponse($repo->findAll());
    }
};

Pass a PSR-11 container when creating the server:

$container = /* your PSR-11 container */;
(new Light\Server($container))->run();

Middleware

Global Middleware

Use pipe() to apply middleware to all routes:

$server = new Light\Server();
$server->pipe(new Light\Server\SecurityHeadersMiddleware());
$server->run();

Attribute-based Middleware (per method)

Attach PSR-15 middleware to a specific handler method using PHP attributes:

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

#[\Attribute]
class AuthMiddleware implements MiddlewareInterface
{
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        // auth logic ...
        return $handler->handle($request);
    }
}

return new class {
    #[AuthMiddleware]
    public function get(): ResponseInterface { /* ... */ }
};

Built-in Middleware

CorsMiddleware

Handles CORS preflight (OPTIONS) requests and adds CORS headers to all responses.

  • OPTIONS requests are intercepted before routing and return 204 No Content with CORS headers
  • All other requests pass through normally with CORS headers appended
$server = new Light\Server();
$server->pipe(new Light\Server\CorsMiddleware(
    allowedOrigins:   ['https://example.com'],
    allowedMethods:   ['GET', 'POST', 'PUT', 'DELETE'],
    allowedHeaders:   ['Content-Type', 'Authorization'],
    allowCredentials: true,
    maxAge:           3600,
));
$server->run();

All constructor parameters are optional:

Parameter Default Description
allowedOrigins ['*'] Allowed origins. Use ['*'] for wildcard
allowedMethods ['GET','POST','PUT','PATCH','DELETE','OPTIONS'] Allowed HTTP methods
allowedHeaders ['Content-Type','Authorization'] Allowed request headers
allowCredentials false Set true to send Access-Control-Allow-Credentials: true
maxAge 86400 Preflight cache duration in seconds

Note: When using allowCredentials: true, allowedOrigins must list specific origins — wildcard * does not work with credentials.

SecurityHeadersMiddleware

Adds common security response headers:

Header Value
X-Content-Type-Options nosniff
X-Frame-Options DENY
X-XSS-Protection 1; mode=block
Referrer-Policy strict-origin-when-cross-origin
Content-Security-Policy default-src 'self'
$server = new Light\Server();
$server->pipe(new Light\Server\SecurityHeadersMiddleware());
$server->run();

Testing

composer install
./vendor/bin/phpunit

The test suite runs against PHP 8.1, 8.2, 8.3, 8.4, and 8.5 via the GitHub Actions matrix in .github/workflows/tests.yml.

License

MIT — see the LICENSE file for details.

mathsgod/light-server 适用场景与选型建议

mathsgod/light-server 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 177 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 03 月 18 日, 在 PHP 生态内属于活跃度较高的组件。

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

围绕 mathsgod/light-server 我们能提供哪些服务?
定制开发 / 二次开发

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-03-18