如何用PHP在30分钟内编写REST API
创建自己的REST API是现代后端开发人员的关键技能之一。许多新手认为这需要像Laravel或Symfony这样的重型框架。实际上,用纯PHP编写一个基础的REST API只需半小时。在本文中,我们将逐步讲解如何创建一个RESTful服务,该服务可以立即用于实际项目——从移动应用到单页网站。
我们不会使用第三方库。所有代码都将用vanilla PHP编写。您将学习如何处理HTTP请求、使用JSON、组织路由以及返回正确的HTTP状态码。开始吧!
1. 项目结构与准备
在编写代码之前,我们先创建一个简单的文件结构。我们的API只需要几个文件:
index.php— 入口点,将处理所有请求;.htaccess— 用于将所有请求重定向到index.php(如果您使用Apache);config.php— 包含数据库连接设置的文件(可选)。
创建一个项目文件夹,例如my-rest-api,并将这些文件放入其中。
配置.htaccess
为了确保所有请求都进入我们的主脚本,请在项目根目录创建.htaccess文件:
RewriteEngine OnRewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-dRewriteRule ^(.*)$ index.php [QSA,L]这段代码将所有不指向实际文件或文件夹的请求重定向到index.php。QSA参数保留query字符串。
2. 路由与请求处理
现在我们来编写主文件——index.php。它将接收请求,确定HTTP方法(GET, POST, PUT, DELETE)和路径,然后调用相应的处理程序。
基础路由
从一个简单的例子开始。创建一个路由数组和一个用于处理它们的函数:
<?phpheader('Content-Type: application/json');header('Access-Control-Allow-Origin: *');header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');header('Access-Control-Allow-Headers: Content-Type');
$method = $_SERVER['REQUEST_METHOD'];$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
// 去掉末尾的斜杠$path = rtrim($path, '/');
// 简单的路由switch (true) { case $path === '/api/users' && $method === 'GET': getUsers(); break; case $path === '/api/users' && $method === 'POST': createUser(); break; case preg_match('/^\\/api\\/users\\/(\\d+)$/', $path, $matches) && $method === 'GET': getUser($matches[1]); break; default: http_response_code(404); echo json_encode(['error' => 'Route not found']); break;}
function getUsers() { // 占位符 echo json_encode(['users' => ['Alice', 'Bob', 'Charlie']]);}
function getUser($id) { echo json_encode(['user' => ['id' => $id, 'name' => 'User ' . $id]]);}
function createUser() { $input = json_decode(file_get_contents('php://input'), true); echo json_encode(['message' => 'User created', 'data' => $input]);}?>请注意几个重要点:
- 我们设置了
Content-Type: application/json头——所有响应都将是JSON格式。 - CORS头允许来自任何域的请求(用于开发)。
- POST/PUT请求的正文通过
php://input读取。
3. 数据库操作
真正的API很少使用占位符。我们通过PDO添加MySQL连接。创建config.php文件:
<?phpdefine('DB_HOST', 'localhost');define(```