PHP与API接口开发实战

发布时间:2026/6/1 6:21:03

PHP与API接口开发实战 PHP与API接口开发实战现在的Web开发基本都离不开API。PHP开发RESTful API很方便今天说说从设计到实现的完整流程。先从一个最简单的API接口开始。接收请求参数处理业务逻辑返回JSON响应。php// 设置响应头header(Content-Type: application/json; charsetutf-8);header(Access-Control-Allow-Origin: *);header(Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS);header(Access-Control-Allow-Headers: Content-Type, Authorization);// 处理预检请求if ($_SERVER[REQUEST_METHOD] OPTIONS) {http_response_code(200);exit;}// 解析请求体$input json_decode(file_get_contents(php://input), true) ?? [];// 获取请求方法$method $_SERVER[REQUEST_METHOD];$path parse_url($_SERVER[REQUEST_URI], PHP_URL_PATH);// 简单的API响应函数function jsonResponse(mixed $data, int $code 200): void{http_response_code($code);echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);exit;}function errorResponse(string $message, int $code 400): void{jsonResponse([error true, message $message], $code);}// 路由处理$path trim($path, /);$parts explode(/, $path);if ($parts[0] api ($parts[1] ?? ) users) {$userId $parts[2] ?? null;// 根据请求方法处理switch ($method) {case GET:if ($userId) {jsonResponse([id $userId, name 张三, email zhangsantest.com]);} else {jsonResponse([[id 1, name 张三],[id 2, name 李四],]);}break;case POST:jsonResponse([message 用户创建成功,id 3,data $input,], 201);break;case PUT:jsonResponse([message 用户更新成功, id $userId]);break;case DELETE:jsonResponse([message 用户删除成功, id $userId]);break;default:errorResponse(不支持的请求方法, 405);}} else {errorResponse(接口不存在, 404);}?路由分发是API的基础上面的代码硬编码了路由实际项目中会用更灵活的方式。php// 路由类class Router{private array $routes [];public function get(string $path, callable $handler): void{$this-routes[GET][] [path $path, handler $handler];}public function post(string $path, callable $handler): void{$this-routes[POST][] [path $path, handler $handler];}public function put(string $path, callable $handler): void{$this-routes[PUT][] [path $path, handler $handler];}public function delete(string $path, callable $handler): void{$this-routes[DELETE][] [path $path, handler $handler];}public function dispatch(string $method, string $uri): void{$uri parse_url($uri, PHP_URL_PATH);foreach ($this-routes[$method] ?? [] as $route) {$pattern preg_replace(/\{(\w)\}/, (?P$1[^/]), $route[path]);$pattern #^ . $pattern . $#;if (preg_match($pattern, $uri, $matches)) {$params array_filter($matches, is_string, ARRAY_FILTER_USE_KEY);header(Content-Type: application/json; charsetutf-8);$result ($route[handler])($params);echo json_encode($result, JSON_UNESCAPED_UNICODE);return;}}http_response_code(404);echo json_encode([error 接口不存在]);}}$router new Router();$router-get(/api/users, function () {return [[id 1, name 张三, email zhangsantest.com],[id 2, name 李四, email lisitest.com],];});$router-get(/api/users/{id}, function ($params) {$id $params[id];return [id (int)$id, name 用户{$id}, email user{$id}test.com];});$router-post(/api/users, function () {$input json_decode(file_get_contents(php://input), true);return [message 创建成功, data $input];});$router-dispatch($_SERVER[REQUEST_METHOD], $_SERVER[REQUEST_URI]);?API的认证和授权是安全的关键。JWTJSON Web Token是目前最常用的认证方式。php// 简单的JWT实现class JWT{private static string $secret your-secret-key-change-in-production;public static function encode(array $payload): string{$header self::base64UrlEncode(json_encode([typ JWT,alg HS256,]));$payload[iat] $payload[iat] ?? time();$payload[exp] $payload[exp] ?? time() 3600;$payloadEncoded self::base64UrlEncode(json_encode($payload));$signature self::base64UrlEncode(hash_hmac(sha256, $header.$payloadEncoded, self::$secret, true));return $header.$payloadEncoded.$signature;}public static function decode(string $token): ?array{$parts explode(., $token);if (count($parts) ! 3) return null;[$header, $payload, $signature] $parts;$expectedSignature self::base64UrlEncode(hash_hmac(sha256, $header.$payload, self::$secret, true));if (!hash_equals($expectedSignature, $signature)) return null;$data json_decode(self::base64UrlDecode($payload), true);if (!$data || (isset($data[exp]) $data[exp] time())) return null;return $data;}private static function base64UrlEncode(string $data): string{return rtrim(strtr(base64_encode($data), /, -_), );}private static function base64UrlDecode(string $data): string{return base64_decode(strtr($data, -_, /));}}// 生成token$token JWT::encode([user_id 123, role admin]);echo JWT Token: $token\n;// 验证token$decoded JWT::decode($token);if ($decoded) {echo 用户ID: {$decoded[user_id]}\n;echo 角色: {$decoded[role]}\n;} else {echo Token无效\n;}// API认证中间件function authMiddleware(): ?array{$headers getallheaders();$authHeader $headers[Authorization] ?? $headers[authorization] ?? ;if (!preg_match(/^Bearer\s(.)$/, $authHeader, $matches)) {http_response_code(401);echo json_encode([error 未提供认证token]);exit;}$user JWT::decode($matches[1]);if ($user null) {http_response_code(401);echo json_encode([error token无效或已过期]);exit;}return $user;}// 受保护的路由$router-get(/api/profile, function () {$user authMiddleware();return [user_id $user[user_id], role $user[role]];});?API的版本管理也很重要常见的做法是在URL或请求头中指定版本。php// URL版本号// /api/v1/users// /api/v2/users// 请求头版本号// Accept: application/vnd.app.v1json// 版本路由$router-get(/api/v1/users, function () {return [version v1, users []];});$router-get(/api/v2/users, function () {return [version v2, users [], meta [total 0]];});?分页是API列表接口的标准做法。phpfunction paginatedResponse(array $items, int $total, int $page, int $perPage): array{return [data $items,meta [current_page $page,per_page $perPage,total $total,total_pages ceil($total / $perPage),has_more $page * $perPage $total,],links [first /api/users?page1,prev $page 1 ? /api/users?page . ($page - 1) : null,next $page * $perPage $total ? /api/users?page . ($page 1) : null,last /api/users?page . ceil($total / $perPage),],];}?错误处理在API中比Web页面更重要因为客户端依赖HTTP状态码和错误信息来做决策。php// 统一错误处理class ApiException extends RuntimeException{public function __construct(string $message,int $code 400,private array $details []) {parent::__construct($message, $code);}public function getDetails(): array{return $this-details;}public function toResponse(): array{$response [error true,message $this-getMessage(),code $this-getCode(),];if (!empty($this-details)) {$response[details] $this-details;}return $response;}}// 全局异常处理set_exception_handler(function (Throwable $e) {if ($e instanceof ApiException) {http_response_code($e-getCode());echo json_encode($e-toResponse(), JSON_UNESCAPED_UNICODE);} else {http_response_code(500);echo json_encode([error true,message $_SERVER[APP_ENV] development ? $e-getMessage() : 服务器内部错误,], JSON_UNESCAPED_UNICODE);error_log(API错误: {$e-getMessage()} in {$e-getFile()}:{$e-getLine()});}});throw new ApiException(参数验证失败, 422, [name [名称不能为空],email [邮箱格式不正确],]);?API开发中请求日志、限流、文档生成也是必不可少的部分。好的API设计要遵循RESTful规范使用正确的HTTP方法和状态码统一的响应格式完善的错误信息。把这些基础打好了API用起来才顺手。

相关新闻