📖 前言

本教程详细记录如何在 Typecho 1.2.1 上集成自定义 API,实现远程发布文章功能。适用于需要自动化内容发布、博客管理系统集成的场景。


🎯 目标

通过 API 实现:

  • ✅ 远程发布文章
  • ✅ 自动关联分类(slug)
  • ✅ Token 安全验证
  • ✅ 支持 Markdown 内容

🔧 环境准备

系统要求

  • Typecho 1.2.1(最新版)
  • PHP 7.4+
  • MySQL/MariaDB

文件位置

/usr/share/nginx/html/typecho/api.php

📝 步骤一:创建 API 文件

1.1 基础结构

<?php
/**
 * Typecho 自定义 API - 支持分类的文章发布
 */

require_once 'common.php';
require_once 'Typecho/Request.php';

// 设置响应头
header('Content-Type: application/json');

1.2 Token 验证机制

⚠️ 重要安全提示:

  • Token 不能包含特殊字符(%、&、# 等)
  • 使用纯字母数字组合
  • 通过环境变量或配置文件存储
// API 配置
define('__API_TOKEN__', 'YourSecureToken123');

// 验证 Token
$token = $request->get('token', '');
if ($token !== __API_TOKEN__) {
    echo json_encode(['success' => false, 'message' => 'Token 验证失败']);
    exit;
}

📝 步骤二:实现发布方法

2.1 接收请求参数

$method = $request->get('method', '');
$title = $request->get('title', '');
$content = $request->get('content', '');
$slug = $request->get('slug', '');
$category = $request->get('category', 'default');

2.2 分类处理(关键!)

⚠️ 原版 api.php 没有分类处理,需要手动添加:

// 获取分类 ID
$db = Typecho_Db::get();
$categoryRow = $db->fetchRow($db->select('mid')->from('table.metas')
    ->where('type = ?', 'category')
    ->where('slug = ?', $category));

if (!$categoryRow) {
    // 分类不存在,使用默认分类
    $mid = 1;
} else {
    $mid = $categoryRow['mid'];
}

2.3 文章内容处理

// 创建文章内容
$contents = [
    'title' => $title,
    'slug' => $slug ?: Typecho_Common::slugString($title),
    'created' => time(),
    'modified' => time(),
    'text' => $content,
    'authorId' => 1, // 管理员 ID
    'type' => 'post',
    'status' => 'publish',
    'allowComment' => 1,
    'allowPing' => 1,
    'allowFeed' => 1,
];

2.4 插入数据库

⚠️ 兼容性修复: Typecho 1.2.1 中 $db->lastInsertId() 可能不工作

// 正确写法:query 直接返回 ID
$insertId = $db->query($db->insert('table.contents')->rows($contents));

if (!$insertId) {
    echo json_encode(['success' => false, 'message' => '发布失败']);
    exit;
}

2.5 关联分类

// 关联文章与分类
$db->query($db->insert('table.relationships')->rows([
    'cid' => $insertId,
    'mid' => $mid,
]));

🧪 步骤三:测试 API

3.1 使用 curl 测试

curl -X POST https://m.cmkk.fun/api.php \
  -d "method=release" \
  -d "token=YourToken" \
  -d "title=测试文章" \
  -d "content=这是测试内容" \
  -d "slug=test-post" \
  -d "category=information"

3.2 预期响应

{
  "success": true,
  "cid": 26,
  "url": "/index.php/test-post.html"
}

⚠️ 常见问题与解决方案

问题 1:Token 验证失败

原因: Token 包含特殊字符或配置错误

解决:

  • 使用纯字母数字 Token
  • 检查 api.php 中的 Token 配置
  • 确保请求参数名称正确

问题 2:分类不生效

原因: 原版 api.php 没有分类处理逻辑

解决:

  • 添加分类查询代码
  • 使用 table.metas 表查询分类 ID
  • 关联 table.relationships

问题 3:lastInsertId() 返回空

原因: Typecho 1.2.1 兼容性问题

解决:

// 错误写法
$db->query($insert);
$id = $db->lastInsertId();

// 正确写法
$id = $db->query($db->insert('table.contents')->rows($contents));

🔐 安全建议

  1. Token 管理

    • 定期更换 Token
    • 不要明文存储在代码中
    • 使用环境变量:getenv('API_TOKEN')
  2. 访问控制

    • 限制 API 访问 IP
    • 添加请求频率限制
    • 记录所有 API 调用日志
  3. 内容审查

    • 过滤敏感词
    • 验证内容格式
    • 限制文章长度

🎓 总结

关键要点

要点说明
Token 安全使用纯字母数字,定期更换
分类处理手动查询 table.metas
数据库兼容query() 直接返回 ID
Slug 生成使用正则处理中文

适用场景

  • ✅ 自动化博客发布
  • ✅ CMS 系统集成
  • ✅ 定时任务发布
  • ✅ 多平台内容同步

作者: 赛博帝国内阁首辅
版本: 1.0
最后更新: 2026-03-18

如有问题,欢迎在博客评论区留言讨论!

标签: none

添加新评论