本文目录导读:

我来详细介绍 PHP API 网关的实现方式和相关内容:
什么是 API 网关
API 网关是一个服务器,作为 API 前端的唯一入口,主要功能包括:
- 请求路由
- 认证授权
- 限流熔断
- 日志监控
- 协议转换
- 负载均衡
PHP 实现 API 网关的方式
1 使用现有框架
Kong Gateway(推荐)
// Kong 的 PHP 客户端
composer require kong/kong
use Kong\Kong;
$kong = new Kong('http://localhost:8001');
// 创建服务
$kong->services()->create([
'name' => 'user-service',
'url' => 'http://user-service:8080'
]);
// 创建路由
$kong->routes()->create([
'services' => ['user-service'],
'hosts' => ['api.example.com'],
'paths' => ['/users']
]);
API Platform
// composer require api-platform/api-platform
use ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase;
// 配置 API 网关
api_platform:
mapping:
paths: ['%kernel.project_dir%/src/Entity'] 'My API Gateway'
version: '1.0.0'
2 自定义实现
基础网关实现
<?php
class ApiGateway {
private $routes = [];
private $middlewares = [];
// 注册路由
public function addRoute($path, $target, $methods = ['GET']) {
$this->routes[] = [
'path' => $path,
'target' => $target,
'methods' => $methods
];
}
// 添加中间件
public function addMiddleware($middleware) {
$this->middlewares[] = $middleware;
}
// 处理请求
public function handle(Request $request) {
// 执行中间件
foreach ($this->middlewares as $middleware) {
$response = $middleware->handle($request);
if ($response) {
return $response;
}
}
// 路由匹配
$route = $this->matchRoute($request);
if (!$route) {
return new Response('Not Found', 404);
}
// 转发请求
return $this->forwardRequest($request, $route);
}
private function matchRoute($request) {
foreach ($this->routes as $route) {
if ($request->getPath() === $route['path'] &&
in_array($request->getMethod(), $route['methods'])) {
return $route;
}
}
return null;
}
private function forwardRequest($request, $route) {
// 使用 Guzzle 转发请求
$client = new GuzzleHttp\Client();
try {
$response = $client->request(
$request->getMethod(),
$route['target'] . $request->getPath(),
[
'headers' => $request->getHeaders(),
'body' => $request->getBody()
]
);
return new Response(
$response->getBody(),
$response->getStatusCode(),
$response->getHeaders()
);
} catch (Exception $e) {
return new Response('Service Unavailable', 503);
}
}
}
3 使用 Slim 框架实现
<?php
require 'vendor/autoload.php';
use Slim\Factory\AppFactory;
use Slim\Middleware\ErrorMiddleware;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
$app = AppFactory::create();
// 认证中间件
$authMiddleware = function (Request $request, $handler) {
$token = $request->getHeaderLine('Authorization');
if (!$token || !$this->validateToken($token)) {
$response = new \Slim\Psr7\Response();
$response->getBody()->write(json_encode(['error' => 'Unauthorized']));
return $response->withStatus(401);
}
return $handler->handle($request);
};
// 路由配置
$app->group('/api/v1', function ($group) use ($authMiddleware) {
// 用户服务路由
$group->get('/users', function (Request $request, Response $response) {
return forwardToService('http://user-service:8080', $request, $response);
})->add($authMiddleware);
// 订单服务路由
$group->post('/orders', function (Request $request, Response $response) {
return forwardToService('http://order-service:8080', $request, $response);
})->add($authMiddleware);
});
$app->run();
// 请求转发函数
function forwardToService($serviceUrl, Request $request, Response $response) {
$client = new GuzzleHttp\Client();
try {
$targetResponse = $client->request(
$request->getMethod(),
$serviceUrl . $request->getUri()->getPath(),
[
'headers' => $request->getHeaders(),
'body' => $request->getBody()
]
);
$response->getBody()->write($targetResponse->getBody());
return $response->withStatus($targetResponse->getStatusCode());
} catch (Exception $e) {
$response->getBody()->write(json_encode(['error' => 'Service unavailable']));
return $response->withStatus(503);
}
}
关键功能实现
1 限流中间件
<?php
class RateLimiter {
private $redis;
private $limit = 100; // 每分钟限制
private $window = 60; // 时间窗口(秒)
public function __construct($redis) {
$this->redis = $redis;
}
public function handle($request) {
$ip = $request->getClientIp();
$key = "rate_limit:{$ip}";
$current = $this->redis->get($key);
if ($current >= $this->limit) {
return new Response('Rate limit exceeded', 429);
}
$this->redis->incr($key);
$this->redis->expire($key, $this->window);
return null; // 继续处理
}
}
2 路由配置示例
<?php
return [
'routes' => [
[
'path' => '/api/users',
'methods' => ['GET', 'POST'],
'target' => 'http://user-service:8000',
'middlewares' => ['auth', 'rate_limit'],
'timeout' => 30
],
[
'path' => '/api/orders',
'methods' => ['GET'],
'target' => 'http://order-service:8000',
'middlewares' => ['auth', 'log'],
'timeout' => 60
]
],
'middlewares' => [
'auth' => AuthMiddleware::class,
'rate_limit' => RateLimiter::class,
'log' => LogMiddleware::class
],
'services' => [
'user-service' => 'http://user-service:8000',
'order-service' => 'http://order-service:8000',
'payment-service' => 'http://payment-service:8000'
]
];
最佳实践建议
1 使用成熟的解决方案
推荐方案:
- Kong Gateway - 功能最全面的 API 网关
- API Platform - Symfony 生态的 API 网关
- Amazon API Gateway - 云原生方案
- Nginx + Lua - 高性能方案
2 性能优化
// 使用连接池
$pool = new ConnectionPool([
'max_connections' => 10,
'min_connections' => 2
]);
// 启用缓存
$cache = new RedisCache();
$cache->set('routes', $routes, 3600);
// 异步处理
$promises = [];
foreach ($routes as $route) {
$promises[] = $client->requestAsync('GET', $route['target']);
}
$results = GuzzleHttp\Promise\settle($promises)->wait();
3 监控和日志
// 集成监控
$monitor = new MetricsCollector();
$monitor->track('request_count', 1);
$monitor->track('response_time', $duration);
// 日志记录
$logger = new Monolog\Logger('api_gateway');
$logger->info('Request processed', [
'path' => $request->getPath(),
'method' => $request->getMethod(),
'duration' => $duration
]);
实际项目示例
// 完整网关入口文件
<?php
require 'vendor/autoload.php';
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class Gateway
{
private $config;
private $container;
public function __construct($configPath)
{
$this->config = require $configPath;
$this->initContainer();
}
public function run()
{
$request = Request::createFromGlobals();
$response = $this->handle($request);
$response->send();
}
private function handle(Request $request): Response
{
try {
// 路由匹配
$route = $this->routeMatcher->match($request);
// 执行中间件链
$response = $this->executeMiddlewareChain($request, $route);
// 转发请求
return $this->forwardRequest($request, $route);
} catch (Exception $e) {
return new Response(
json_encode(['error' => $e->getMessage()]),
500,
['Content-Type' => 'application/json']
);
}
}
}
// 启动网关
$gateway = new Gateway('config/gateway.php');
$gateway->run();
选择合适的 API 网关方案取决于你的具体需求:
- 小型项目:使用 Slim/Laravel 自定义实现
- 中型项目:使用 Kong 或 API Platform
- 大型项目:使用云服务商提供的 API 网关