nextphp / rest
NextPHP Rest 包为 PHP 开发者提供强大的路由能力和 HTTP 处理功能。该包支持所有 RESTful 方法(GET、POST、PUT、DELETE、PATCH、OPTIONS、HEAD、TRACE、CONNECT、PRI)以及多种响应格式,如 JSON、XML、HTML、TEXT 和 CSV。它通过允许开发者使用属性定义路由和控制器,简化了 API 的创建,确保代码库整洁高效。
Requires
- php: ^8.1
README
NextPHP Rest 包为 PHP 开发者提供强大的路由能力和 HTTP 处理功能。该包支持所有 RESTful 方法(GET、POST、PUT、DELETE、PATCH、OPTIONS、HEAD、TRACE、CONNECT、PRI)以及多种响应格式,如 JSON、XML、HTML、TEXT 和 CSV。它通过允许开发者使用属性定义路由和控制器,简化了 API 的创建,确保代码库整洁高效。
此包是 NextPHP 框架 的一部分,NextPHP 框架是一个现代、轻量级的 PHP 框架,旨在提高性能和可扩展性。NextPHP 的目标是提供一套全面的工具和库,以简化开发过程。
功能
- 支持所有 RESTful 方法(GET、POST、PUT、DELETE、PATCH、OPTIONS、HEAD、TRACE、CONNECT、PRI)
- 响应格式:JSON、XML、HTML、TEXT、CSV
- 基于属性的路线定义
- 中间件支持
- 易于与现有项目集成
安装
通过 Composer 安装
要安装 NextPHP Rest 包,您需要使用 Composer 将其添加到您的项目中。
composer require nextphp/rest
使用 NextPHP Rest 的示例项目
这是一个示例项目,展示了 NextPHP Rest 包的使用,该包包括路由和 HTTP 处理功能。
基本用法 定义路由 使用属性将 HTTP 方法映射到控制器操作。
用法
使用控制器
<?php namespace Example\Controller; use NextPHP\Rest\Http\Get; use NextPHP\Rest\Http\Post; use NextPHP\Rest\Http\Put; use NextPHP\Rest\Http\Delete; use NextPHP\Rest\Http\Patch; use NextPHP\Rest\Http\RouteGroup; use NextPHP\Rest\Http\Middleware; #[RouteGroup('/api/users')] class UserController { #[Get('/')] public function getAllUsers() { // logic to get all users } #[Post('/')] public function createUser() { // logic to create a user } #[Put('/{id}')] public function updateUser($id) { // logic to update a user } #[Delete('/{id}')] public function deleteUser($id) { // logic to delete a user } #[Patch('/{id}')] public function partiallyUpdateUser($id) { // logic to partially update a user } }
高级实体用法
中间件用法
使用属性定义中间件并将其应用到路由上。您可以使用 #[Middleware(AuthMiddleware::class)]
将中间件应用到整个控制器类,或使用方法特定的属性将其应用到单个路由上。
#[RouteGroup('/api')] #[Middleware(AuthMiddleware::class)] class UserController { #[Get('/users')] #[Middleware(AuthMiddleware::class)] public function getAllUsers() { // logic to get all users } }
生成 AuthMiddleware 类
AuthMiddleware 处理 JWT 认证检查 HTTP 请求和响应。
<?php namespace Example; use NextPHP\Rest\Http\Request; use NextPHP\Rest\Http\Response; use Firebase\JWT\JWT; use Firebase\JWT\Key; /** * Class AuthMiddleware * * A simple implementation of a PSR-7 http message interface and PSR-15 http handlers. * * Middleware for handling JWT authentication. * * @package NextPHP\Rest\Middleware */ class AuthMiddleware { /** * Handles the incoming request and checks for JWT authentication. * * @param Request $request The HTTP request. * @param Response $response The HTTP response. * @param callable $next The next middleware or controller. * @return Response The modified response. */ public function handle(Request $request, Response $response, callable $next): Response { $authHeader = $request->getHeaders()['Authorization'] ?? ''; if (!$authHeader) { return $response->withStatus(401)->withJSON(['error' => 'Unauthorized']); } list($jwt) = sscanf($authHeader, 'Bearer %s'); if (!$jwt) { return $response->withStatus(401)->withJSON(['error' => 'Unauthorized']); } try { $decoded = JWT::decode($jwt, new Key('your-secret-key', 'HS256')); // Token is valid, proceed with the request return $next($request, $response); } catch (\Exception $e) { return $response->withStatus(401)->withJSON(['error' => 'Unauthorized']); } } }
服务层示例
服务提供业务逻辑并与存储库交互。
<?php namespace Example; #[Service(description: 'User management service')] class UserService { private UserRepository $userRepository; public function __construct(UserRepository $userRepository) { $this->userRepository = $userRepository; } #[Transactional] public function registerUser(array $userData): User { $user = new User(); $user->name = $userData['name']; $user->email = $userData['email']; $user->password = password_hash($userData['password'], PASSWORD_DEFAULT); $userArray = [ 'name' => $user->name, 'email' => $user->email, 'password' => $user->password, ]; $this->userRepository->save($userArray); return $user; } public function getAllUsers(): array { return $this->userRepository->findAll(); } public function getUserById(int $id): ?User { $userArray = $this->userRepository->find($id); if (!$userArray) { return null; } $user = new User(); $user->id = $userArray['id']; $user->name = $userArray['name']; $user->email = $userArray['email']; $user->password = $userArray['password'] ?? ''; return $user; } public function updateUser(int $id, array $data): ?User { $user = $this->getUserById($id); if (!$user) { return null; } foreach ($data as $key => $value) { if (property_exists($user, $key)) { $user->$key = $value; } } $userArray = get_object_vars($user); $this->userRepository->update($id, $userArray); return $user; } public function deleteUser(int $id): bool { $user = $this->getUserById($id); if (!$user) { return false; } $this->userRepository->delete($id); return true; } }
示例项目
项目结构示例
example/
├── src/
│ ├── Entity/User.php
│ ├── Repository/UserRepository.php
│ ├── Service/UserService.php
│ ├── Resource/UserResource.php
├── example.php
├── composer.json
└── README.md
示例或 example.php
要使用 NextPHP Rest 包,您可以创建一个 index.php 文件并使用路由器处理各种 HTTP 请求。以下是一个示例:
示例 index.php
<?php require_once __DIR__ . '/vendor/autoload.php'; use NextPHP\Rest\DI\Container; use NextPHP\Rest\Router; use NextPHP\Rest\Http\Request; use NextPHP\Rest\Http\Response; use NextPHP\App\Resource\UserResource; use NextPHP\App\Resource\PostResource; $container = new Container(); $router = new Router([ 'baseUri' => '/nextphp-beta', 'allowedOrigins' => [ 'http://allowed-origin.com' => ['GET', 'POST'], 'http://another-allowed-origin.com' => ['GET', 'PUT'], '*' => ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD', 'TRACE', 'CONNECT', 'PRI'] ] ], $container); // DI $router->registerRoutesFromController(UserResource::class); $router->registerRoutesFromController(PostResource::class); $uri = $_SERVER['REQUEST_URI']; $method = $_SERVER['REQUEST_METHOD']; $request = new Request($method, $uri, getallheaders(), file_get_contents('php://input'), $_GET, $_POST); $response = new Response(); $response = $router->dispatch($request, $response); if ($response) { http_response_code($response->getStatusCode()); foreach ($response->getHeaders() as $name => $value) { header("$name: $value"); } echo $response->getBody(); } else { http_response_code(500); echo json_encode(['error' => 'Internal Server Error', 'message' => 'No response returned.']); }
贡献
我们欢迎贡献!以下是您可以如何帮助:
- 报告问题:发现了错误?在 GitHub 上报告。
- 建议功能:有想法?与我们分享。
- 提交拉取请求:改进代码库。
- 增强文档:帮助我们改进我们的文档。
有关更多详细信息,请参阅我们的 贡献指南。
资源
加入我们的社区
联系我们
- 电子邮件: support@nextphp.io
- 论坛: NextPHP Mastodon
- GitHub 问题: NextPHP GitHub
感谢您成为 NextPHP 社区的一员!
常见问题解答 (FAQ)
问:如何定义路由?
答:使用 #[Get]、#[Post]、#[Put]、#[Delete]、#[Patch] 等属性来定义路由处理程序的方法。使用 #[RouteGroup] 来定义一组路由的公共前缀。
更多详细信息,请参阅我们的常见问题解答。