ZitBBS Discuz! X3.4 搜索帖子 API 开发文档


简介

本文档旨在为开发者提供 ZitBBS Discuz! X3.4 搜索帖子 API 的详细信息,包括安装步骤、API 端点、请求参数、认证机制、响应格式、错误处理以及使用示例。通过该 API,外部应用可以方便地在 ZitBBS 论坛中搜索帖子标题,实现数据集成和扩展功能。

功能概述

安装与部署

先决条件

部署步骤

  1. 获取 API 脚本

    将以下 PHP 脚本保存为 search_posts_api.php

  2. 上传脚本

    search_posts_api.php 文件上传到 Discuz! 安装目录的根目录或指定的子目录。例如,上传到根目录后,API 的访问 URL 为 https://www.yoursite.com/search_posts_api.php

  3. 配置 API 密钥

    在脚本中设置您的 API 密钥(详细见 认证机制)。

  4. 设置文件权限

    确保 search_posts_api.php 文件具有适当的读取权限(通常为 644)。

  5. 测试 API

    通过浏览器或工具(如 Postman)访问 API,确认其正常工作。

API 端点

URL: https://www.yoursite.com/search_posts_api.php
方法: GET
格式: JSON

请求参数

参数名称 类型 必填 描述
api_key string 用于认证的 API 密钥。需与服务器端设置匹配。
q string 搜索关键词。
page integer 当前页码。默认值为 1
pagesize integer 每页显示的记录数。默认值为 10,最大值为 100

认证机制

为了确保 API 的安全性,所有请求必须携带有效的 api_key 参数。只有提供正确 API 密钥的请求才能访问 API。

设置 API 密钥

  1. 定义 API 密钥

    search_posts_api.php 中定义一个常量 API_KEY,用于存储您的 API 密钥。

    define('API_KEY', 'YOUR_SECURE_API_KEY');

    注意:请将 'YOUR_SECURE_API_KEY' 替换为您选择的安全密钥,避免使用简单或易猜测的字符串。

  2. 验证 API 密钥

    在脚本中获取客户端提供的 api_key 参数,并与服务器端定义的 API_KEY 进行比对。

    
    // 获取客户端提供的 API 密钥
    $client_api_key = isset($_GET['api_key']) ? trim($_GET['api_key']) : '';
    
    // 验证 API 密钥
    if ($client_api_key !== API_KEY) {
        http_response_code(403);
        echo json_encode(['error' => '无效的 API 密钥']);
        exit();
    }
                    

    如果提供的 api_key 不匹配,API 将返回 403 Forbidden 状态码和错误信息。

响应格式

所有成功的 API 响应将以 JSON 格式返回,包含以下字段:

字段名称 类型 描述
query string 搜索关键词。
page integer 当前页码。
pagesize integer 每页显示的记录数。
total integer 符合条件的总记录数。
total_pages integer 总页数。
posts array 搜索结果的帖子列表。每个帖子包含以下子字段:

每个帖子的子字段

子字段名称 类型 描述
pid integer 帖子 ID。
tid integer 线程 ID。
subject string 帖子标题(线程主题)。
author string 发帖作者。
dateline string 发帖日期和时间,格式为 YYYY-MM-DD HH:MM:SS

示例响应

{
    "query": "Discuz",
    "page": 1,
    "pagesize": 10,
    "total": 25,
    "total_pages": 3,
    "posts": [
        {
            "pid": 12345,
            "tid": 67890,
            "subject": "如何使用 Discuz! X3.4 搜索帖子",
            "author": "张三",
            "dateline": "2024-04-26 15:30:00"
        },
        {
            "pid": 12346,
            "tid": 67891,
            "subject": "Discuz! X3.4 安装指南",
            "author": "李四",
            "dateline": "2024-04-25 14:20:00"
        }
        // 更多帖子...
    ]
}

错误处理

API 使用标准的 HTTP 状态码来指示请求的处理结果:

状态码 含义 描述
200 OK 请求成功并返回结果。
400 Bad Request 请求参数有误,如缺少必要参数。
403 Forbidden 无效的 API 密钥或无权限访问。
429 Too Many Requests 请求频率过高,超过速率限制。
500 Internal Server Error 服务器内部错误,如数据库连接失败。

每个错误响应都包含一个 error 字段,描述具体的错误信息。

示例请求

使用浏览器访问

在浏览器地址栏输入以下 URL,替换为您的实际 API URL 和参数:

https://www.yoursite.com/search_posts_api.php?api_key=YOUR_SECURE_API_KEY&q=Discuz&page=1&pagesize=10

使用 curl 命令行工具

curl "https://www.yoursite.com/search_posts_api.php?api_key=YOUR_SECURE_API_KEY&q=Discuz&page=1&pagesize=10"

使用 Postman

  1. 打开 Postman。
  2. 创建一个新的 GET 请求。
  3. 输入 URL:
    https://www.yoursite.com/search_posts_api.php
  4. Params 标签下,添加以下参数:
    Key Value
    api_key YOUR_SECURE_API_KEY
    q Discuz
    page 1
    pagesize 10
  5. 点击 Send 发送请求,并查看响应结果。

安全性与优化建议

1. 隐藏和保护 API 密钥

避免将 API 密钥硬编码在公开的代码中。推荐将密钥存储在服务器端的配置文件中,并确保该文件不被公开访问。

示例

创建配置文件 api_config.php

<?php
// api_config.php

define('API_KEY', 'YOUR_SECURE_API_KEY');
?>

search_posts_api.php 中引入配置文件:

require_once './api_config.php';

修改 API 密钥验证部分:

// 获取客户端提供的 API 密钥
$client_api_key = isset($_GET['api_key']) ? trim($_GET['api_key']) : '';

// 验证 API 密钥
if ($client_api_key !== API_KEY) {
    http_response_code(403);
    echo json_encode(['error' => '无效的 API 密钥']);
    exit();
}
        

2. 使用 HTTPS 加密传输

确保您的网站启用了 HTTPS,以保护 API 请求中的敏感数据(如 API 密钥)不被窃听或篡改。

3. 实现速率限制

为防止 API 被滥用,建议实现请求速率限制。例如,每个 IP 每分钟最多请求 60 次。

示例:基于文件的简单速率限制

// 定义限制
define('MAX_REQUESTS_PER_MINUTE', 60);

// 获取客户端 IP
$client_ip = $_SERVER['REMOTE_ADDR'];

// 定义计数器文件路径
$counter_file = sys_get_temp_dir() . '/api_rate_limit_' . md5($client_ip) . '.txt';

// 获取当前时间戳(分钟级)
$current_minute = floor(time() / 60);

// 读取计数器
if (file_exists($counter_file)) {
    list($timestamp, $count) = explode(':', file_get_contents($counter_file));
    if ($timestamp === (string)$current_minute) {
        if ($count >= MAX_REQUESTS_PER_MINUTE) {
            http_response_code(429);
            echo json_encode(['error' => '请求过于频繁,请稍后再试']);
            exit();
        }
        $count++;
    } else {
        $count = 1;
    }
} else {
    $count = 1;
}

// 写入计数器
file_put_contents($counter_file, $current_minute . ':' . $count);
        

注意:这种方法适用于低流量环境。对于高流量或分布式系统,建议使用集中式缓存(如 Redis)来管理速率限制。

4. 使用全文索引提高搜索效率

如果您的帖子数量较多,建议在数据库中为 forum_thread.subject 字段添加全文索引,以提高搜索性能。

添加全文索引的 SQL 语句示例

ALTER TABLE pre_forum_thread ADD FULLTEXT(subject);

修改 PHP 脚本以使用 MATCH...AGAINST 语法:

$search_sql = "
    SELECT p.pid, p.tid, t.subject, p.author, p.dateline
    FROM {$post_table} p
    JOIN {$thread_table} t ON p.tid = t.tid
    WHERE MATCH(t.subject) AGAINST(? IN NATURAL LANGUAGE MODE)
    ORDER BY p.dateline DESC
    LIMIT ? OFFSET ?
";

$stmt->bind_param('sii', $query, $pagesize, $offset);
        

注意:

5. 实现数据缓存

对于频繁相同的查询,可以实现数据缓存,减少数据库查询次数,提升 API 响应速度。

示例:使用文件缓存

// 定义缓存目录
define('CACHE_DIR', sys_get_temp_dir() . '/api_cache/');

// 确保缓存目录存在
if (!file_exists(CACHE_DIR)) {
    mkdir(CACHE_DIR, 0755, true);
}

// 定义缓存文件路径
$cache_key = md5("search_posts_{$query}_{$page}_{$pagesize}");
$cache_file = CACHE_DIR . $cache_key . '.json';

// 定义缓存有效期(秒)
$cache_time = 60; // 缓存 1 分钟

// 检查缓存是否存在且有效
if (file_exists($cache_file) && (time() - filemtime($cache_file) < $cache_time)) {
    // 读取缓存
    echo file_get_contents($cache_file);
    exit();
}

// 生成响应数据
$response = [
    'query'       => $query,
    'page'        => $page,
    'pagesize'    => $pagesize,
    'total'       => $total,
    'total_pages' => $total_pages,
    'posts'       => $posts,
];

// 将响应数据写入缓存
file_put_contents($cache_file, json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));

// 返回响应
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
        

注意:对于高并发环境,建议使用更高效的缓存机制,如 Redis 或 Memcached。

常见问题

1. 无法访问 API(ERR_NAME_NOT_RESOLVED)

原因:

解决方法:

2. API 返回 403 Forbidden 错误

原因:

解决方法:

3. API 返回 400 Bad Request 错误

原因:

解决方法:

4. API 返回 500 Internal Server Error

原因:

解决方法:

5. 搜索结果不准确或为空

原因:

解决方法:

联系方式

如果您在使用 ZitBBS Discuz! X3.4 搜索帖子 API 时遇到问题,或有任何建议和反馈,请通过以下方式联系我们:

我们将尽快回复并协助您解决问题。