PHP 8 中实践 RESTful API,可以通过以下步骤实现一个简单的 RESTful API。我们将以一个管理“用户”的 RESTful API 为例,展示如何在 PHP 8 中处理 HTTP 请求,返回 JSON 格式的数据,并遵循 RESTful 风格。


1. 环境准备

安装 PHP 8 和 Composer

确保你已安装 PHP 8 和 Composer(PHP 的依赖包管理工具)。

创建项目结构

创建一个文件夹,用于存放你的项目,例如 php-restful-api,项目结构如下:

php-restful-api/
├── public/
│   └── index.php            # 入口文件
├── src/
│   ├── UserController.php   # 控制器
│   └── Router.php           # 简单的路由处理
└── composer.json            # Composer 配置文件

2. 创建路由和入口

(1)配置 composer.json

使用 Composer 自动加载文件。运行以下命令初始化项目:

composer init

在提问过程中,默认选项即可,但确保 autoload 设置为 psr-4,如下:

{
  "autoload": {
    "psr-4": {
      "App\\": "src/"
    }
  }
}

运行以下命令生成自动加载文件:

composer dump-autoload

(2)入口文件 - public/index.php

此文件将用来处理所有 HTTP 请求。

<?php

// 自动加载
require_once __DIR__ . '/../vendor/autoload.php';

use App\Router;
use App\UserController;

// 定义路由规则
$router = new Router();

// 用户资源的 RESTful 路由
$router->get('/users', [UserController::class, 'getAllUsers']); // 获取所有用户
$router->get('/users/{id}', [UserController::class, 'getUserById']); // 获取单个用户
$router->post('/users', [UserController::class, 'createUser']); // 创建用户
$router->put('/users/{id}', [UserController::class, 'updateUser']); // 更新用户
$router->delete('/users/{id}', [UserController::class, 'deleteUser']); // 删除用户

// 处理请求
$router->dispatch($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']);

(3)简单的路由实现 - src/Router.php

实现一个简单的路由器,用于匹配 URL 和方法,并调用对应的控制器方法。

<?php

namespace App;

class Router
{
    private array $routes = [];

    public function get(string $path, callable|array $handler): void
    {
        $this->addRoute('GET', $path, $handler);
    }

    public function post(string $path, callable|array $handler): void
    {
        $this->addRoute('POST', $path, $handler);
    }

    public function put(string $path, callable|array $handler): void
    {
        $this->addRoute('PUT', $path, $handler);
    }

    public function delete(string $path, callable|array $handler): void
    {
        $this->addRoute('DELETE', $path, $handler);
    }

    private function addRoute(string $method, string $path, callable|array $handler): void
    {
        $this->routes[] = compact('method', 'path', 'handler');
    }

    public function dispatch(string $method, string $uri): void
    {
        foreach ($this->routes as $route) {
            $pattern = '@^' . preg_replace('/\{([a-zA-Z0-9_]+)\}/', '([a-zA-Z0-9_]+)', $route['path']) . '$@';
            if ($method === $route['method'] && preg_match($pattern, $uri, $matches)) {
                array_shift($matches); // 移除第一个完整匹配的结果
                if (is_array($route['handler'])) {
                    [$class, $method] = $route['handler'];
                    call_user_func_array([new $class, $method], $matches);
                } else {
                    call_user_func_array($route['handler'], $matches);
                }
                return;
            }
        }

        // 如果没有找到匹配的路由,返回 404
        http_response_code(404);
        echo json_encode(['error' => 'Route not found']);
    }
}

3. 创建控制器

创建 src/UserController.php

在这个文件中,我们实现对用户资源的 CRUD 操作。为了简化这部分逻辑,我们用一个数组模拟数据库数据。

<?php

namespace App;

class UserController
{
    private static array $users = [
        ['id' => 1, 'name' => 'Alice', 'email' => '[email protected]'],
        ['id' => 2, 'name' => 'Bob', 'email' => '[email protected]']
    ];

    public function getAllUsers(): void
    {
        echo json_encode(self::$users);
    }

    public function getUserById($id): void
    {
        foreach (self::$users as $user) {
            if ($user['id'] == $id) {
                echo json_encode($user);
                return;
            }
        }
        http_response_code(404);
        echo json_encode(['error' => 'User not found']);
    }

    public function createUser(): void
    {
        $data = json_decode(file_get_contents('php://input'), true);

        // 简单的验证
        if (!isset($data['name']) || !isset($data['email'])) {
            http_response_code(400);
            echo json_encode(['error' => 'Invalid input']);
            return;
        }

        $newUser = [
            'id' => count(self::$users) + 1,
            'name' => $data['name'],
            'email' => $data['email']
        ];
        self::$users[] = $newUser;

        http_response_code(201);
        echo json_encode($newUser);
    }

    public function updateUser($id): void
    {
        $data = json_decode(file_get_contents('php://input'), true);

        foreach (self::$users as &$user) {
            if ($user['id'] == $id) {
                $user['name'] = $data['name'] ?? $user['name'];
                $user['email'] = $data['email'] ?? $user['email'];

                echo json_encode($user);
                return;
            }
        }

        http_response_code(404);
        echo json_encode(['error' => 'User not found']);
    }

    public function deleteUser($id): void
    {
        foreach (self::$users as $key => $user) {
            if ($user['id'] == $id) {
                unset(self::$users[$key]);
                http_response_code(204); // No Content
                return;
            }
        }

        http_response_code(404);
        echo json_encode(['error' => 'User not found']);
    }
}

4. 测试 RESTful API

启动内置服务器

在项目根目录运行以下命令,启动 PHP 的内置服务器:

php -S localhost:8000 -t public

测试 API

使用工具如 PostmancURL 测试 API。

  • 获取所有用户:

    curl -X GET http://localhost:8000/users
  • 获取单个用户:

    curl -X GET http://localhost:8000/users/1
  • 创建用户:

    curl -X POST http://localhost:8000/users -H "Content-Type: application/json" -d '{"name": "Charlie", "email": "[email protected]"}'
  • 更新用户:

    curl -X PUT http://localhost:8000/users/1 -H "Content-Type: application/json" -d '{"name": "Updated Name"}'
  • 删除用户:

    curl -X DELETE http://localhost:8000/users/1

总结

以上是一个使用 PHP 8 构建 RESTful API 的完整实践。它包含了基本的路由处理、控制器实现和 JSON 数据返回,遵循了 RESTful API 的设计原则,可以根据需要扩展功能或引入框架(如 Laravel)。

标签: PHP, REST-API

评论已关闭