Skip to content

API和接口

概述

API(应用程序编程接口)和接口是PHP开发中的关键概念。本章涵盖面向对象的接口、与Web API的交互、创建RESTful服务以及消费外部API。理解这些概念对于构建现代化、互联的应用程序至关重要。

面向对象接口

基本接口定义

php
<?php
// 接口定义
interface PaymentProcessorInterface {
    public function processPayment($amount, $currency);
    public function refundPayment($transactionId);
    public function getTransactionStatus($transactionId);
}

// 接口实现
class StripePaymentProcessor implements PaymentProcessorInterface {
    private $apiKey;
    
    public function __construct($apiKey) {
        $this->apiKey = $apiKey;
    }
    
    public function processPayment($amount, $currency) {
        // Stripe特定的支付处理
        return [
            'success' => true,
            'transaction_id' => 'stripe_' . uniqid(),
            'amount' => $amount,
            'currency' => $currency
        ];
    }
    
    public function refundPayment($transactionId) {
        // Stripe特定的退款逻辑
        return [
            'success' => true,
            'refund_id' => 'refund_' . uniqid(),
            'transaction_id' => $transactionId
        ];
    }
    
    public function getTransactionStatus($transactionId) {
        // Stripe特定的状态检查
        return '已完成';
    }
}

class PayPalPaymentProcessor implements PaymentProcessorInterface {
    private $clientId;
    private $clientSecret;
    
    public function __construct($clientId, $clientSecret) {
        $this->clientId = $clientId;
        $this->clientSecret = $clientSecret;
    }
    
    public function processPayment($amount, $currency) {
        // PayPal特定的支付处理
        return [
            'success' => true,
            'transaction_id' => 'paypal_' . uniqid(),
            'amount' => $amount,
            'currency' => $currency
        ];
    }
    
    public function refundPayment($transactionId) {
        // PayPal特定的退款逻辑
        return [
            'success' => true,
            'refund_id' => 'pp_refund_' . uniqid(),
            'transaction_id' => $transactionId
        ];
    }
    
    public function getTransactionStatus($transactionId) {
        // PayPal特定的状态检查
        return '待处理';
    }
}

// 使用多态性
function processOrder($processor, $amount, $currency) {
    if (!$processor instanceof PaymentProcessorInterface) {
        throw new InvalidArgumentException('处理器必须实现PaymentProcessorInterface');
    }
    
    $result = $processor->processPayment($amount, $currency);
    
    if ($result['success']) {
        echo "支付处理成功:{$result['transaction_id']}\n";
        return $result['transaction_id'];
    } else {
        echo "支付失败\n";
        return false;
    }
}

$stripeProcessor = new StripePaymentProcessor('sk_test_123');
$paypalProcessor = new PayPalPaymentProcessor('client_123', 'secret_456');

processOrder($stripeProcessor, 100.00, 'USD');
processOrder($paypalProcessor, 75.50, 'EUR');
?>

多接口实现

php
<?php
interface Readable {
    public function read();
}

interface Writable {
    public function write($data);
}

interface Seekable {
    public function seek($position);
    public function tell();
}

// 实现多个接口的类
class FileHandler implements Readable, Writable, Seekable {
    private $file;
    private $position = 0;
    
    public function __construct($filename, $mode = 'r+') {
        $this->file = fopen($filename, $mode);
        if (!$this->file) {
            throw new Exception("无法打开文件:$filename");
        }
    }
    
    public function read() {
        return fread($this->file, 1024);
    }
    
    public function write($data) {
        return fwrite($this->file, $data);
    }
    
    public function seek($position) {
        $this->position = $position;
        return fseek($this->file, $position);
    }
    
    public function tell() {
        return ftell($this->file);
    }
    
    public function __destruct() {
        if ($this->file) {
            fclose($this->file);
        }
    }
}

// 接口继承
interface DatabaseConnectionInterface {
    public function connect();
    public function disconnect();
}

interface QueryableInterface extends DatabaseConnectionInterface {
    public function query($sql);
    public function prepare($sql);
}

interface TransactionalInterface extends QueryableInterface {
    public function beginTransaction();
    public function commit();
    public function rollback();
}

class MySQLConnection implements TransactionalInterface {
    private $connection;
    private $inTransaction = false;
    
    public function connect() {
        // MySQL连接逻辑
        echo "已连接到MySQL\n";
    }
    
    public function disconnect() {
        // MySQL断开连接逻辑
        echo "已从Mysql断开连接\n";
    }
    
    public function query($sql) {
        echo "执行查询:$sql\n";
        return ['result' => 'data'];
    }
    
    public function prepare($sql) {
        echo "准备语句:$sql\n";
        return new stdClass(); // 模拟预处理语句
    }
    
    public function beginTransaction() {
        $this->inTransaction = true;
        echo "事务已开始\n";
    }
    
    public function commit() {
        if ($this->inTransaction) {
            $this->inTransaction = false;
            echo "事务已提交\n";
        }
    }
    
    public function rollback() {
        if ($this->inTransaction) {
            $this->inTransaction = false;
            echo "事务已回滚\n";
        }
    }
}
?>

接口常量和类型提示

php
<?php
interface LoggerInterface {
    const LEVEL_DEBUG = 1;
    const LEVEL_INFO = 2;
    const LEVEL_WARNING = 3;
    const LEVEL_ERROR = 4;
    const LEVEL_CRITICAL = 5;
    
    public function log($level, $message, array $context = []);
}

class FileLogger implements LoggerInterface {
    private $logFile;
    
    public function __construct($logFile) {
        $this->logFile = $logFile;
    }
    
    public function log($level, $message, array $context = []) {
        $levelNames = [
            self::LEVEL_DEBUG => '调试',
            self::LEVEL_INFO => '信息',
            self::LEVEL_WARNING => '警告',
            self::LEVEL_ERROR => '错误',
            self::LEVEL_CRITICAL => '严重'
        ];
        
        $levelName = $levelNames[$level] ?? '未知';
        $timestamp = date('Y-m-d H:i:s');
        $contextStr = !empty($context) ? json_encode($context) : '';
        
        $logEntry = "[$timestamp] [$levelName] $message $contextStr\n";
        file_put_contents($this->logFile, $logEntry, FILE_APPEND | LOCK_EX);
    }
}

// 使用接口进行类型提示
class Application {
    private $logger;
    
    public function __construct(LoggerInterface $logger) {
        $this->logger = $logger;
    }
    
    public function run() {
        $this->logger->log(LoggerInterface::LEVEL_INFO, '应用程序已启动');
        
        try {
            // 应用程序逻辑
            $this->processData();
        } catch (Exception $e) {
            $this->logger->log(
                LoggerInterface::LEVEL_ERROR, 
                '应用程序错误:' . $e->getMessage(),
                ['exception' => get_class($e), 'file' => $e->getFile(), 'line' => $e->getLine()]
            );
        }
        
        $this->logger->log(LoggerInterface::LEVEL_INFO, '应用程序已结束');
    }
    
    private function processData() {
        $this->logger->log(LoggerInterface::LEVEL_DEBUG, '正在处理数据');
        // 处理逻辑在这里
    }
}

$logger = new FileLogger('app.log');
$app = new Application($logger);
$app->run();
?>

与Web API的交互

发送HTTP请求

php
<?php
// 使用cURL发送HTTP请求
class HttpClient {
    private $baseUrl;
    private $defaultHeaders;
    
    public function __construct($baseUrl = '', $defaultHeaders = []) {
        $this->baseUrl = rtrim($baseUrl, '/');
        $this->defaultHeaders = $defaultHeaders;
    }
    
    public function get($endpoint, $headers = []) {
        return $this->makeRequest('GET', $endpoint, null, $headers);
    }
    
    public function post($endpoint, $data = null, $headers = []) {
        return $this->makeRequest('POST', $endpoint, $data, $headers);
    }
    
    public function put($endpoint, $data = null, $headers = []) {
        return $this->makeRequest('PUT', $endpoint, $data, $headers);
    }
    
    public function delete($endpoint, $headers = []) {
        return $this->makeRequest('DELETE', $endpoint, null, $headers);
    }
    
    private function makeRequest($method, $endpoint, $data = null, $headers = []) {
        $url = $this->baseUrl . '/' . ltrim($endpoint, '/');
        $allHeaders = array_merge($this->defaultHeaders, $headers);
        
        $curl = curl_init();
        
        curl_setopt_array($curl, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_HTTPHEADER => $this->formatHeaders($allHeaders),
            CURLOPT_TIMEOUT => 30,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_SSL_VERIFYPEER => false, // Only for development
        ]);
        
        if ($data !== null) {
            if (is_array($data) || is_object($data)) {
                curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
                $allHeaders['Content-Type'] = 'application/json';
            } else {
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            }
        }
        
        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $error = curl_error($curl);
        
        curl_close($curl);
        
        if ($error) {
            throw new Exception("cURL错误:$error");
        }
        
        return [
            'status_code' => $httpCode,
            'body' => $response,
            'data' => json_decode($response, true)
        ];
    }
    
    private function formatHeaders($headers) {
        $formatted = [];
        foreach ($headers as $key => $value) {
            $formatted[] = "$key: $value";
        }
        return $formatted;
    }
}

// 使用示例
$client = new HttpClient('https://jsonplaceholder.typicode.com', [
    'User-Agent' => 'PHP HTTP Client 1.0'
]);

try {
    // GET请求
    $response = $client->get('/posts/1');
    echo "状态:{$response['status_code']}\n";
    echo "标题:{$response['data']['title']}\n";
    
    // POST请求
    $newPost = [
        'title' => '我的新文章',
        'body' => '这是我新文章的内容。',
        'userId' => 1
    ];
    
    $response = $client->post('/posts', $newPost);
    echo "创建的文章ID:{$response['data']['id']}\n";
    
} catch (Exception $e) {
    echo "错误:" . $e->getMessage() . "\n";
}
?>

API响应处理

php
<?php
class ApiResponse {
    private $statusCode;
    private $headers;
    private $body;
    private $data;
    
    public function __construct($statusCode, $headers, $body) {
        $this->statusCode = $statusCode;
        $this->headers = $headers;
        $this->body = $body;
        $this->data = json_decode($body, true);
    }
    
    public function isSuccessful() {
        return $this->statusCode >= 200 && $this->statusCode < 300;
    }
    
    public function isClientError() {
        return $this->statusCode >= 400 && $this->statusCode < 500;
    }
    
    public function isServerError() {
        return $this->statusCode >= 500;
    }
    
    public function getStatusCode() {
        return $this->statusCode;
    }
    
    public function getHeaders() {
        return $this->headers;
    }
    
    public function getBody() {
        return $this->body;
    }
    
    public function getData() {
        return $this->data;
    }
    
    public function getHeader($name) {
        return $this->headers[$name] ?? null;
    }
}

// 带响应处理的API客户端
class WeatherApiClient {
    private $httpClient;
    private $apiKey;
    
    public function __construct($apiKey) {
        $this->apiKey = $apiKey;
        $this->httpClient = new HttpClient('https://api.openweathermap.org/data/2.5');
    }
    
    public function getCurrentWeather($city) {
        try {
            $response = $this->httpClient->get("/weather", [
                'q' => $city,
                'appid' => $this->apiKey,
                'units' => 'metric'
            ]);
            
            if ($response['status_code'] === 200) {
                return [
                    'success' => true,
                    'data' => [
                        'city' => $response['data']['name'],
                        'temperature' => $response['data']['main']['temp'],
                        'description' => $response['data']['weather'][0]['description'],
                        'humidity' => $response['data']['main']['humidity']
                    ]
                ];
            } else {
                return [
                    'success' => false,
                    'error' => $response['data']['message'] ?? 'Unknown error'
                ];
            }
        } catch (Exception $e) {
            return [
                'success' => false,
                'error' => $e->getMessage()
            ];
        }
    }
    
    public function getForecast($city, $days = 5) {
        try {
            $response = $this->httpClient->get("/forecast", [
                'q' => $city,
                'appid' => $this->apiKey,
                'units' => 'metric',
                'cnt' => $days * 8 // 每天8次预报(每3小时一次)
            ]);
            
            if ($response['status_code'] === 200) {
                $forecasts = [];
                foreach ($response['data']['list'] as $item) {
                    $forecasts[] = [
                        'datetime' => $item['dt_txt'],
                        'temperature' => $item['main']['temp'],
                        'description' => $item['weather'][0]['description']
                    ];
                }
                
                return [
                    'success' => true,
                    'data' => [
                        'city' => $response['data']['city']['name'],
                        'forecasts' => $forecasts
                    ]
                ];
            } else {
                return [
                    'success' => false,
                    'error' => $response['data']['message'] ?? 'Unknown error'
                ];
            }
        } catch (Exception $e) {
            return [
                'success' => false,
                'error' => $e->getMessage()
            ];
        }
    }
}

// 使用
$weatherClient = new WeatherApiClient('your_api_key_here');

$currentWeather = $weatherClient->getCurrentWeather('伦敦');
if ($currentWeather['success']) {
    $data = $currentWeather['data'];
    echo "{$data['city']}当前天气:{$data['temperature']}°C,{$data['description']}\n";
} else {
    echo "错误:{$currentWeather['error']}\n";
}
?>

创建RESTful API

基本REST API结构

php
<?php
// 简单的REST API路由器
class RestApiRouter {
    private $routes = [];
    
    public function get($path, $handler) {
        $this->addRoute('GET', $path, $handler);
    }
    
    public function post($path, $handler) {
        $this->addRoute('POST', $path, $handler);
    }
    
    public function put($path, $handler) {
        $this->addRoute('PUT', $path, $handler);
    }
    
    public function delete($path, $handler) {
        $this->addRoute('DELETE', $path, $handler);
    }
    
    private function addRoute($method, $path, $handler) {
        $this->routes[] = [
            'method' => $method,
            'path' => $path,
            'handler' => $handler
        ];
    }
    
    public function handle() {
        $method = $_SERVER['REQUEST_METHOD'];
        $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
        
        foreach ($this->routes as $route) {
            if ($route['method'] === $method && $this->matchPath($route['path'], $path)) {
                $params = $this->extractParams($route['path'], $path);
                return call_user_func($route['handler'], $params);
            }
        }
        
        $this->sendResponse(404, ['error' => '路由未找到']);
    }
    
    private function matchPath($routePath, $requestPath) {
        $routePattern = preg_replace('/\{[^}]+\}/', '([^/]+)', $routePath);
        return preg_match("#^{$routePattern}$#", $requestPath);
    }
    
    private function extractParams($routePath, $requestPath) {
        $params = [];
        $routeParts = explode('/', $routePath);
        $requestParts = explode('/', $requestPath);
        
        for ($i = 0; $i < count($routeParts); $i++) {
            if (preg_match('/\{([^}]+)\}/', $routeParts[$i], $matches)) {
                $paramName = $matches[1];
                $params[$paramName] = $requestParts[$i] ?? null;
            }
        }
        
        return $params;
    }
    
    private function sendResponse($statusCode, $data) {
        http_response_code($statusCode);
        header('Content-Type: application/json');
        echo json_encode($data);
        exit;
    }
}

// 用户API控制器
class UserApiController {
    private $users = [
        1 => ['id' => 1, 'name' => '张三', 'email' => 'zhangsan@example.com'],
        2 => ['id' => 2, 'name' => '李四', 'email' => 'lisi@example.com'],
        3 => ['id' => 3, 'name' => '王五', 'email' => 'wangwu@example.com']
    ];
    
    public function getAllUsers($params) {
        $this->sendResponse(200, array_values($this->users));
    }
    
    public function getUser($params) {
        $id = (int)$params['id'];
        
        if (isset($this->users[$id])) {
            $this->sendResponse(200, $this->users[$id]);
        } else {
            $this->sendResponse(404, ['error' => 'User not found']);
        }
    }
    
    public function createUser($params) {
        $input = json_decode(file_get_contents('php://input'), true);
        
        if (!$input || !isset($input['name']) || !isset($input['email'])) {
            $this->sendResponse(400, ['error' => '姓名和邮箱是必需的']);
        }
        
        $id = max(array_keys($this->users)) + 1;
        $user = [
            'id' => $id,
            'name' => $input['name'],
            'email' => $input['email']
        ];
        
        $this->users[$id] = $user;
        $this->sendResponse(201, $user);
    }
    
    public function updateUser($params) {
        $id = (int)$params['id'];
        $input = json_decode(file_get_contents('php://input'), true);
        
        if (!isset($this->users[$id])) {
            $this->sendResponse(404, ['error' => '用户未找到']);
        }
        
        if ($input) {
            if (isset($input['name'])) {
                $this->users[$id]['name'] = $input['name'];
            }
            if (isset($input['email'])) {
                $this->users[$id]['email'] = $input['email'];
            }
        }
        
        $this->sendResponse(200, $this->users[$id]);
    }
    
    public function deleteUser($params) {
        $id = (int)$params['id'];
        
        if (isset($this->users[$id])) {
            unset($this->users[$id]);
            $this->sendResponse(204, null);
        } else {
            $this->sendResponse(404, ['error' => 'User not found']);
        }
    }
    
    private function sendResponse($statusCode, $data) {
        http_response_code($statusCode);
        header('Content-Type: application/json');
        
        if ($data !== null) {
            echo json_encode($data);
        }
        
        exit;
    }
}

// API设置
$router = new RestApiRouter();
$userController = new UserApiController();

// 定义路由
$router->get('/api/users', [$userController, 'getAllUsers']);
$router->get('/api/users/{id}', [$userController, 'getUser']);
$router->post('/api/users', [$userController, 'createUser']);
$router->put('/api/users/{id}', [$userController, 'updateUser']);
$router->delete('/api/users/{id}', [$userController, 'deleteUser']);

// 处理请求
$router->handle();
?>

API认证和中间件

php
<?php
// JWT令牌处理器(简化版)
class JwtHandler {
    private $secret;
    
    public function __construct($secret) {
        $this->secret = $secret;
    }
    
    public function generateToken($payload) {
        $header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']);
        $payload = json_encode($payload);
        
        $base64Header = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header));
        $base64Payload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload));
        
        $signature = hash_hmac('sha256', $base64Header . "." . $base64Payload, $this->secret, true);
        $base64Signature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));
        
        return $base64Header . "." . $base64Payload . "." . $base64Signature;
    }
    
    public function validateToken($token) {
        $parts = explode('.', $token);
        
        if (count($parts) !== 3) {
            return false;
        }
        
        [$header, $payload, $signature] = $parts;
        
        $validSignature = hash_hmac('sha256', $header . "." . $payload, $this->secret, true);
        $validBase64Signature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($validSignature));
        
        if ($signature !== $validBase64Signature) {
            return false;
        }
        
        $decodedPayload = json_decode(base64_decode(str_replace(['-', '_'], ['+', '/'], $payload)), true);
        
        // 检查过期时间
        if (isset($decodedPayload['exp']) && $decodedPayload['exp'] < time()) {
            return false;
        }
        
        return $decodedPayload;
    }
}

// 认证中间件
class AuthMiddleware {
    private $jwtHandler;
    
    public function __construct(JwtHandler $jwtHandler) {
        $this->jwtHandler = $jwtHandler;
    }
    
    public function authenticate() {
        $headers = getallheaders();
        $authHeader = $headers['Authorization'] ?? '';
        
        if (!preg_match('/Bearer\s+(.*)$/i', $authHeader, $matches)) {
            $this->sendUnauthorized('缺少或无效的授权头');
        }
        
        $token = $matches[1];
        $payload = $this->jwtHandler->validateToken($token);
        
        if (!$payload) {
            $this->sendUnauthorized('无效或已过期的令牌');
        }
        
        return $payload;
    }
    
    private function sendUnauthorized($message) {
        http_response_code(401);
        header('Content-Type: application/json');
        echo json_encode(['error' => $message]);
        exit;
    }
}

// 受保护的API控制器
class ProtectedApiController {
    private $authMiddleware;
    
    public function __construct(AuthMiddleware $authMiddleware) {
        $this->authMiddleware = $authMiddleware;
    }
    
    public function getProfile($params) {
        $user = $this->authMiddleware->authenticate();
        
        // 返回用户资料
        $this->sendResponse(200, [
            'id' => $user['user_id'],
            'name' => $user['name'],
            'email' => $user['email']
        ]);
    }
    
    public function updateProfile($params) {
        $user = $this->authMiddleware->authenticate();
        $input = json_decode(file_get_contents('php://input'), true);
        
        // 更新用户资料逻辑在这里
        
        $this->sendResponse(200, ['message' => '资料更新成功']);
    }
    
    private function sendResponse($statusCode, $data) {
        http_response_code($statusCode);
        header('Content-Type: application/json');
        echo json_encode($data);
        exit;
    }
}

// 登录控制器
class AuthController {
    private $jwtHandler;
    private $users = [
        'zhangsan@example.com' => ['id' => 1, 'name' => '张三', 'password' => 'password123'],
        'lisi@example.com' => ['id' => 2, 'name' => '李四', 'password' => 'secret456']
    ];
    
    public function __construct(JwtHandler $jwtHandler) {
        $this->jwtHandler = $jwtHandler;
    }
    
    public function login($params) {
        $input = json_decode(file_get_contents('php://input'), true);
        
        if (!isset($input['email']) || !isset($input['password'])) {
            $this->sendResponse(400, ['error' => '邮箱和密码是必需的']);
        }
        
        $email = $input['email'];
        $password = $input['password'];
        
        if (!isset($this->users[$email]) || $this->users[$email]['password'] !== $password) {
            $this->sendResponse(401, ['error' => '无效的凭据']);
        }
        
        $user = $this->users[$email];
        $payload = [
            'user_id' => $user['id'],
            'name' => $user['name'],
            'email' => $email,
            'exp' => time() + 3600 // 1小时过期
        ];
        
        $token = $this->jwtHandler->generateToken($payload);
        
        $this->sendResponse(200, [
            'token' => $token,
            'user' => [
                'id' => $user['id'],
                'name' => $user['name'],
                'email' => $email
            ]
        ]);
    }
    
    private function sendResponse($statusCode, $data) {
        http_response_code($statusCode);
        header('Content-Type: application/json');
        echo json_encode($data);
        exit;
    }
}

// 设置
$jwtHandler = new JwtHandler('your-secret-key');
$authMiddleware = new AuthMiddleware($jwtHandler);
$authController = new AuthController($jwtHandler);
$protectedController = new ProtectedApiController($authMiddleware);

// 路由
$router = new RestApiRouter();
$router->post('/api/login', [$authController, 'login']);
$router->get('/api/profile', [$protectedController, 'getProfile']);
$router->put('/api/profile', [$protectedController, 'updateProfile']);

$router->handle();
?>

API文档和测试

API文档生成器

php
<?php
/**
 * @api {get} /api/users 获取所有用户
 * @apiName GetUsers
 * @apiGroup User
 * 
 * @apiSuccess {Object[]} users 用户列表
 * @apiSuccess {Number} users.id 用户ID
 * @apiSuccess {String} users.name 用户姓名
 * @apiSuccess {String} users.email 用户邮箱
 * 
 * @apiSuccessExample Success-Response:
 *     HTTP/1.1 200 OK
 *     [
 *       {
 *         "id": 1,
 *         "name": "张三",
 *         "email": "zhangsan@example.com"
 *       }
 *     ]
 */

class ApiDocumentationGenerator {
    private $routes = [];
    
    public function addRoute($method, $path, $description, $parameters = [], $responses = []) {
        $this->routes[] = [
            'method' => strtoupper($method),
            'path' => $path,
            'description' => $description,
            'parameters' => $parameters,
            'responses' => $responses
        ];
    }
    
    public function generateHtml() {
        $html = '<!DOCTYPE html>
<html>
<head>
    <title>API文档</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; }
        .route { margin-bottom: 30px; border: 1px solid #ddd; padding: 20px; }
        .method { display: inline-block; padding: 5px 10px; color: white; font-weight: bold; }
        .get { background-color: #61affe; }
        .post { background-color: #49cc90; }
        .put { background-color: #fca130; }
        .delete { background-color: #f93e3e; }
        .path { font-family: monospace; font-size: 18px; margin-left: 10px; }
        .parameters, .responses { margin-top: 15px; }
        table { width: 100%; border-collapse: collapse; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
    </style>
</head>
<body>
    <h1>API文档</h1>';
        
        foreach ($this->routes as $route) {
            $methodClass = strtolower($route['method']);
            $html .= "<div class='route'>";
            $html .= "<span class='method {$methodClass}'>{$route['method']}</span>";
            $html .= "<span class='path'>{$route['path']}</span>";
            $html .= "<p>{$route['description']}</p>";
            
            if (!empty($route['parameters'])) {
                $html .= "<div class='parameters'><h4>参数:</h4>";
                $html .= "<table><tr><th>名称</th><th>类型</th><th>必需</th><th>描述</th></tr>";
                foreach ($route['parameters'] as $param) {
                    $required = $param['required'] ? '是' : '否';
                    $html .= "<tr><td>{$param['name']}</td><td>{$param['type']}</td><td>{$required}</td><td>{$param['description']}</td></tr>";
                }
                $html .= "</table></div>";
            }
            
            if (!empty($route['responses'])) {
                $html .= "<div class='responses'><h4>响应:</h4>";
                foreach ($route['responses'] as $response) {
                    $html .= "<h5>HTTP {$response['code']}</h5>";
                    $html .= "<pre>" . htmlspecialchars($response['example']) . "</pre>";
                }
                $html .= "</div>";
            }
            
            $html .= "</div>";
        }
        
        $html .= '</body></html>';
        return $html;
    }
}

// 使用
$docs = new ApiDocumentationGenerator();

$docs->addRoute('GET', '/api/users', '获取所有用户', [], [
    ['code' => 200, 'example' => json_encode([
        ['id' => 1, 'name' => '张三', 'email' => 'zhangsan@example.com']
    ], JSON_PRETTY_PRINT)]
]);

$docs->addRoute('POST', '/api/users', '创建新用户', [
    ['name' => 'name', 'type' => 'string', 'required' => true, 'description' => '用户姓名'],
    ['name' => 'email', 'type' => 'string', 'required' => true, 'description' => '用户邮箱']
], [
    ['code' => 201, 'example' => json_encode([
        'id' => 4, 'name' => '新用户', 'email' => 'new@example.com'
    ], JSON_PRETTY_PRINT)]
]);

echo $docs->generateHtml();
?>

下一步

现在您已经了解了API和接口,让我们在错误处理中探索错误处理。

实践练习

  1. 为博客系统创建一个完整的RESTful API
  2. 为热门的Web服务(GitHub、Twitter等)构建API客户端
  3. 实现API速率限制和缓存
  4. 创建一个API网关,将请求路由到不同的服务
  5. 构建一个用于实时通知的webhook系统

理解API和接口对于构建现代化、互联的PHP应用程序至关重要!

本站内容仅供学习和研究使用。