本文目录导读:

我来通过一个完整的图书管理系统API案例,展示PHP如何输出JSON数据。
项目结构
book-api/
├── index.php # 入口文件
├── config/
│ └── database.php # 数据库配置
├── api/
│ ├── books.php # 图书API路由
│ └── response.php # JSON响应工具类
└── models/
└── Book.php # 图书模型
基础配置
database.php - 数据库配置
<?php
// config/database.php
class Database {
private $host = 'localhost';
private $db_name = 'book_store';
private $username = 'root';
private $password = '';
private $conn;
public function getConnection() {
$this->conn = null;
try {
$this->conn = new PDO(
"mysql:host={$this->host};dbname={$this->db_name}",
$this->username,
$this->password
);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo json_encode(['error' => $e->getMessage()]);
}
return $this->conn;
}
}
JSON响应工具类
response.php - JSON输出工具
<?php
// api/response.php
class Response {
// 设置响应头
public static function setHeaders() {
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
}
// 成功响应
public static function success($data, $message = 'Success', $code = 200) {
http_response_code($code);
echo json_encode([
'status' => 'success',
'code' => $code,
'message' => $message,
'data' => $data,
'timestamp' => date('Y-m-d H:i:s')
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit;
}
// 错误响应
public static function error($message, $code = 400, $errors = []) {
http_response_code($code);
echo json_encode([
'status' => 'error',
'code' => $code,
'message' => $message,
'errors' => $errors,
'timestamp' => date('Y-m-d H:i:s')
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit;
}
}
图书模型
Book.php - 数据访问层
<?php
// models/Book.php
class Book {
private $conn;
private $table = 'books';
public $id;
public $title;
public $author;
public $isbn;
public $price;
public $category;
public $created_at;
public function __construct($db) {
$this->conn = $db;
}
// 获取所有图书
public function getAll() {
$query = "SELECT * FROM {$this->table} ORDER BY created_at DESC";
$stmt = $this->conn->prepare($query);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// 获取单本图书
public function getById($id) {
$query = "SELECT * FROM {$this->table} WHERE id = :id";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(':id', $id);
$stmt->execute();
return $stmt->fetch(PDO::FETCH_ASSOC);
}
// 创建图书
public function create($data) {
$query = "INSERT INTO {$this->table}
(title, author, isbn, price, category)
VALUES (:title, :author, :isbn, :price, :category)";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(':title', $data['title']);
$stmt->bindParam(':author', $data['author']);
$stmt->bindParam(':isbn', $data['isbn']);
$stmt->bindParam(':price', $data['price']);
$stmt->bindParam(':category', $data['category']);
if($stmt->execute()) {
return $this->conn->lastInsertId();
}
return false;
}
// 更新图书
public function update($id, $data) {
$query = "UPDATE {$this->table}
SET title = :title,
author = :author,
isbn = :isbn,
price = :price,
category = :category
WHERE id = :id";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(':id', $id);
$stmt->bindParam(':title', $data['title']);
$stmt->bindParam(':author', $data['author']);
$stmt->bindParam(':isbn', $data['isbn']);
$stmt->bindParam(':price', $data['price']);
$stmt->bindParam(':category', $data['category']);
return $stmt->execute();
}
// 删除图书
public function delete($id) {
$query = "DELETE FROM {$this->table} WHERE id = :id";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(':id', $id);
return $stmt->execute();
}
// 搜索图书
public function search($keyword) {
$query = "SELECT * FROM {$this->table}
WHERE title LIKE :keyword
OR author LIKE :keyword
OR isbn LIKE :keyword";
$keyword = "%{$keyword}%";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(':keyword', $keyword);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
API路由处理
books.php - 主API文件
<?php
// api/books.php
require_once '../config/database.php';
require_once '../models/Book.php';
require_once 'response.php';
// 设置响应头
Response::setHeaders();
// 处理预检请求
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit;
}
// 数据库连接
$database = new Database();
$db = $database->getConnection();
$book = new Book($db);
// 获取请求方法
$method = $_SERVER['REQUEST_METHOD'];
// 解析URL获取ID参数
$request_uri = $_SERVER['REQUEST_URI'];
$path_parts = explode('/', trim($request_uri, '/'));
$id = end($path_parts);
$id = is_numeric($id) ? (int)$id : null;
// 获取请求体数据
$input_data = json_decode(file_get_contents("php://input"), true);
// 路由处理
switch ($method) {
case 'GET':
// 获取所有图书或单本图书
if ($id) {
$result = $book->getById($id);
if ($result) {
Response::success($result, '图书获取成功');
} else {
Response::error('图书不存在', 404);
}
} else {
// 检查是否有搜索参数
if (isset($_GET['search'])) {
$result = $book->search($_GET['search']);
Response::success($result, '搜索结果');
} else {
$result = $book->getAll();
Response::success($result, '图书列表获取成功');
}
}
break;
case 'POST':
// 创建图书 - 显示不同JSON输出方式
if ($input_data) {
// 方法1: 验证输入
$validation = validateBookData($input_data);
if (!$validation['valid']) {
Response::error('数据验证失败', 422, $validation['errors']);
}
// 方法2: 输出创建请求的JSON格式
echo json_encode([
'debug' => [
'received_data' => $input_data,
'content_type' => $_SERVER['CONTENT_TYPE'],
'method' => $method
]
], JSON_PRETTY_PRINT);
// 实际创建操作
$new_id = $book->create($input_data);
if ($new_id) {
$new_book = $book->getById($new_id);
Response::success($new_book, '图书创建成功', 201);
} else {
Response::error('创建失败', 500);
}
} else {
Response::error('请提供图书数据', 400);
}
break;
case 'PUT':
// 更新图书
if ($id && $input_data) {
$validation = validateBookData($input_data);
if (!$validation['valid']) {
Response::error('数据验证失败', 422, $validation['errors']);
}
if ($book->update($id, $input_data)) {
$updated_book = $book->getById($id);
Response::success($updated_book, '图书更新成功');
} else {
Response::error('更新失败', 500);
}
} else {
Response::error('请提供图书ID和数据', 400);
}
break;
case 'DELETE':
// 删除图书
if ($id) {
if ($book->delete($id)) {
Response::success(null, '图书删除成功');
} else {
Response::error('删除失败', 500);
}
} else {
Response::error('请提供图书ID', 400);
}
break;
default:
Response::error('不支持的请求方法', 405);
}
?>
数据库表结构
-- 创建数据库
CREATE DATABASE IF NOT EXISTS book_store;
USE book_store;
-- 创建图书表
CREATE TABLE books (
id INT AUTO_INCREMENT PRIMARY KEY,VARCHAR(255) NOT NULL,
author VARCHAR(255) NOT NULL,
isbn VARCHAR(20) UNIQUE NOT NULL,
price DECIMAL(10, 2) NOT NULL,
category VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 插入测试数据
INSERT INTO books (title, author, isbn, price, category) VALUES
('PHP编程入门', '张三', '978-7-111-11111-1', 59.00, '编程语言'),
('JavaScript高级编程', '李四', '978-7-111-22222-2', 69.00, '前端开发'),
('数据结构与算法', '王五', '978-7-111-33333-3', 79.00, '计算机科学'),
('Python数据分析', '赵六', '978-7-111-44444-4', 89.00, '数据分析');
入口文件
index.php - 入口和路由
<?php
// index.php - API入口文件
// 错误处理设置
error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
// 自定义异常处理
function exception_handler($exception) {
Response::error('服务器内部错误', 500);
}
set_exception_handler('exception_handler');
// 数据验证函数
function validateBookData($data) {
$errors = [];
if (empty($data['title'])) {
$errors[] = '书名不能为空';
}
if (empty($data['author'])) {
$errors[] = '作者不能为空';
}
if (empty($data['isbn'])) {
$errors[] = 'ISBN不能为空';
}
if (!isset($data['price']) || !is_numeric($data['price'])) {
$errors[] = '价格必须是数字';
}
return [
'valid' => empty($errors),
'errors' => $errors
];
}
// 路由到API处理器
require_once 'api/books.php';
?>
使用示例
GET请求 - 获取所有图书
curl http://localhost/book-api/api/books.php
响应JSON:
{
"status": "success",
"code": 200,
"message": "图书列表获取成功",
"data": [
{
"id": 1,
"title": "PHP编程入门",
"author": "张三",
"isbn": "978-7-111-11111-1",
"price": "59.00",
"category": "编程语言",
"created_at": "2024-01-15 10:30:00"
}
],
"timestamp": "2024-01-15 14:30:00"
}
POST请求 - 创建图书
curl -X POST http://localhost/book-api/api/books.php \
-H "Content-Type: application/json" \
-d '{"title":"Node.js入门","author":"钱七","isbn":"978-7-111-55555-5","price":"49.00","category":"后端开发"}'
错误响应示例
{
"status": "error",
"code": 422,
"message": "数据验证失败",
"errors": ["书名不能为空", "价格必须是数字"],
"timestamp": "2024-01-15 14:35:00"
}
关键JSON输出技术总结
-
设置Content-Type头:
header("Content-Type: application/json; charset=UTF-8") -
JSON编码选项:
JSON_UNESCAPED_UNICODE:支持中文JSON_PRETTY_PRINT:格式化输出JSON_NUMERIC_CHECK:数字类型转换
-
状态码设置:
http_response_code(200) -
输入获取:
json_decode(file_get_contents("php://input"), true) -
错误处理:统一的JSON格式错误响应
这个完整的案例展示了如何在实际项目中高效地使用PHP输出JSON数据,包括错误处理、数据验证和格式化输出等最佳实践。