
当老板说"给系统加个AI",你的老项目还在跑 PHP 5.6,服务器连 Composer 都没有装。别慌,30 行 cURL 搞定。
一、为什么是 DeepSeek?
2026 年 8 月,国产大模型 API 已经卷到白菜价。我对比了主流五家:
| 模型 | 输入(元/百万Token) | 输出(元/百万Token) | 特点 |
|---|---|---|---|
| DeepSeek-V4-Flash | 1.00 | 2.00 | 性价比首选,支持百万上下文 |
| DeepSeek-V4-Pro | 3.00 | 6.00 | 复杂推理能力强 |
| Qwen-Turbo | 0.033 | 0.130 | 最便宜,适合批量处理 |
| Qwen3.5-Plus | 2.00 | 2.00 | 中文原生,阿里云生态 |
| GLM-4.7-Flash | 0 | 0 | 免费,200K 上下文 |
最终选 DeepSeek,原因就三条:
- OpenAI 兼容格式,换模型只改一个 URL,不用改代码逻辑
- 中文理解能力强,错别字检查这种活儿精准度直接拉满
- 价格够低,日常 1 万次调用月成本 5-10 块钱,老板看了不心疼
申请地址:platform.deepseek.com ,注册后创建 API Key,5 分钟搞定。
二、整体架构
javascript
浏览器 (ai_demo.html)
↓ POST JSON
PHP 中间层 (ai_helper.php)
↓ cURL 请求
DeepSeek API
↓ JSON 返回
PHP 解析 → 返回前端
三个文件搞定一切:
| 文件 | 作用 | 行数 |
|---|---|---|
ai_config.php |
API 密钥、模型配置、系统提示词、辅助函数 | ~120 行 |
ai_helper.php |
接口路由、参数校验、调用 API、格式化返回 | ~150 行 |
ai_demo.html |
前端页面,三个 Tab 交互 | ~300 行 |
零依赖,不需要 Composer,不需要 SDK,不需要 Node.js。一个支持 cURL 的 PHP 环境就能跑。
三、核心代码
3.1 配置文件 ai_config.php
php
<?php
// API 密钥(替换为你自己的)
$DS_API_KEY = 'sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$DS_API_URL = 'https://api.deepseek.com/chat/completions';
$DS_MODEL = 'deepseek-chat'; // V3 通用模型
// 超时设置
$DS_TIMEOUT = 30;
$DS_CONNECT_TIMEOUT = 10;
// 日志开关(上线后关闭)
$DS_LOG_ENABLED = false;
$DS_LOG_FILE = __DIR__ . '/ai_log.txt';
// 三套系统提示词
$DS_PROMPTS = array(
// 错别字检查:要求返回 JSON 结构
'typo_check' => '你是专业的中文文字校对专家。请检查以下类型错误:'
. "\n1. 错别字(同音字误用,如\"在/再\"、\"的/得/地\")"
. "\n2. 形近字误用(如\"己/已/巳\")"
. "\n3. 多字/漏字/标点错误"
. "\n\n以JSON格式返回:"
. "\n{\"errors\":[{\"wrong\":\"错\",\"correct\":\"对\",\"type\":\"错别字\",\"reason\":\"原因\"}],"
. "\"corrected\":\"修正全文\",\"total\":1}"
. "\n无错误返回:{\"errors\":[],\"corrected\":\"原文\",\"total\":0}",
// 文案解读:多维度分析
'interpret' => '你是资深文案分析专家。请从概括、语气、优点、不足、建议、关键词、评分维度分析,'
. '以JSON格式返回:'
. "\n{\"summary\":\"\",\"tone\":\"\",\"strengths\":[],\"weaknesses\":[],"
. "\"suggestions\":[],\"keywords\":[],\"score\":8}",
// 智能问答:带业务背景的客服
'chat' => '你是「漏刻有时」智能助手,专注于地图开发、数据可视化、GIS技术领域。'
. '回答专业、简洁、实用,使用中文,可适当使用加粗和列表排版。',
);
3.2 API 调用核心函数
这是整个方案的心脏------一个 cURL 封装函数:
php
function ds_call_api($messages, $temperature = 0.7, $maxTokens = 2000) {
global $DS_API_KEY, $DS_API_URL, $DS_MODEL, $DS_TIMEOUT, $DS_CONNECT_TIMEOUT;
$data = array(
'model' => $DS_MODEL,
'messages' => $messages,
'temperature' => $temperature,
'max_tokens' => $maxTokens,
'stream' => false,
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $DS_API_URL);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Authorization: Bearer ' . $DS_API_KEY,
));
curl_setopt($ch, CURLOPT_TIMEOUT, $DS_TIMEOUT);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $DS_CONNECT_TIMEOUT);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 兼容老服务器
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
return array('ok' => false, 'error' => '网络请求失败:' . $curlError);
}
if ($httpCode != 200) {
$errInfo = json_decode($response, true);
$errMsg = isset($errInfo['error']['message'])
? $errInfo['error']['message']
: 'API返回HTTP ' . $httpCode;
return array('ok' => false, 'error' => $errMsg);
}
$result = json_decode($response, true);
$content = $result['choices'][0]['message']['content'];
return array('ok' => true, 'content' => $content);
}
3.3 接口路由 ai_helper.php
中间层做三件事:接收前端请求 → 组装消息调用 API → 按功能格式化返回。
php
<?php
require_once __DIR__ . '/ai_config.php';
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
// CORS 预检
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit;
}
// 仅接受 POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(array('ok' => false, 'error' => '仅支持 POST 请求'));
exit;
}
// 读取参数(兼容 JSON 和表单)
$input = json_decode(file_get_contents('php://input'), true);
if ($input === null) $input = $_POST;
$action = isset($input['action']) ? $input['action'] : 'chat';
$text = isset($input['text']) ? trim($input['text']) : '';
$history = isset($input['history']) ? $input['history'] : array();
// 文本长度限制
$maxLen = $action === 'chat' ? 4000 : 5000;
if (mb_strlen($text, 'UTF-8') > $maxLen) {
echo json_encode(array('ok' => false, 'error' => '文本过长,最大 ' . $maxLen . ' 字'));
exit;
}
// 组装消息
$messages = array(
array('role' => 'system', 'content' => $DS_PROMPTS[$action]),
);
// 智能问答保留最近 10 轮对话
if ($action === 'chat' && !empty($history)) {
foreach (array_slice($history, -10) as $msg) {
$messages[] = array(
'role' => $msg['role'],
'content' => $msg['content'],
);
}
}
$messages[] = array('role' => 'user', 'content' => $text);
// 不同功能设置不同温度
$temp = ($action === 'typo_check') ? 0.1
: (($action === 'interpret') ? 0.3 : 0.7);
$result = ds_call_api($messages, $temp, 2000);
if (!$result['ok']) {
echo json_encode(array('ok' => false, 'error' => $result['error']));
exit;
}
// 错别字和文案解读尝试解析 JSON
if ($action !== 'chat') {
$parsed = ds_extract_json($result['content']);
if ($parsed !== null) {
echo json_encode(array('ok' => true, 'action' => $action, 'data' => $parsed),
JSON_UNESCAPED_UNICODE);
} else {
echo json_encode(array('ok' => true, 'action' => $action, 'raw' => $result['content']),
JSON_UNESCAPED_UNICODE);
}
} else {
echo json_encode(array('ok' => true, 'action' => 'chat', 'reply' => $result['content']),
JSON_UNESCAPED_UNICODE);
}
3.4 前端调用示例
javascript
// 调用错别字检查
async function checkTypo(text) {
const res = await fetch('ai_helper.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'typo_check', text })
});
const json = await res.json();
if (json.ok) {
// json.data.errors → 错误列表
// json.data.corrected → 修正后全文
// json.data.total → 错误数量
renderErrors(json.data);
}
}
// 智能问答(带上下文)
async function sendChat(text) {
const res = await fetch('ai_helper.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'chat',
text: text,
history: chatHistory // 最近10轮对话
})
});
const json = await res.json();
if (json.ok) {
// json.reply → AI回复文本
renderMessage('assistant', json.reply);
}
}
四、三大功能详解
功能一:错别字检查
输入一段文本,AI 逐字扫描,找出同音字误用、形近字混淆、多字漏字、标点错误。
返回示例:
json
{
"ok": true,
"action": "typo_check",
"data": {
"errors": [
{
"wrong": "在那",
"correct": "在哪",
"type": "错别字",
"reason": "「在」表示位置,「哪」用于疑问,此处为疑问语气应使用「在哪」"
},
{
"wrong": "以经",
"correct": "已经",
"type": "错别字",
"reason": "「以」表示用/凭,「已」表示完成,此处表完成应使用「已经」"
}
],
"corrected": "你在哪里?我已经到了。",
"total": 2
}
}
温度参数设为 0.1,让模型尽可能确定性地输出,减少"幻觉"式误判。
前端拿到 errors 数组后,在原文中定位每个错误词,用红色删除线标注错误内容、绿色标注正确写法,旁边列出错误类型和原因说明。
功能二:文案解读
输入一段营销文案或产品描述,AI 从七个维度拆解分析:
| 维度 | 说明 |
|---|---|
| summary | 一句话概括核心卖点 |
| tone | 语气风格分析(活泼/专业/煽情/理性) |
| strengths | 优点列表 |
| weaknesses | 不足之处 |
| suggestions | 优化建议 |
| keywords | 提取关键词 |
| score | 1-10 评分 |
温度参数设为 0.3,保持理性分析风格,不至于太天马行空。
前端用卡片式布局展示:顶部大号评分数字 + 评分条,下方依次是概括、语气、优点(绿色标签)、不足(橙色标签)、建议(蓝色标签)、关键词云。
功能三:智能问答
一个完整的聊天界面,支持多轮上下文对话。系统提示词中内置了业务背景知识,相当于一个"懂行"的客服。
温度参数设为 0.7,让回答更灵活自然。
前端用聊天气泡布局,保留最近 10 轮对话历史通过 history 参数传给后端,PHP 端再转发给 API,实现上下文连贯。
五、PHP 5.6 兼容性踩坑
老系统最头疼的就是 PHP 版本。以下是我踩过的坑,分享给同样被 5.6 困扰的同学:
| 坑点 | PHP 7+ 写法 | PHP 5.6 兼容写法 |
|---|---|---|
| 空值判断 | $a = $b ?? 'default' |
$a = isset($b) ? $b : 'default' |
| 数组常量 | define('CONFIG', [...]) |
$CONFIG = array(...) |
| 返回类型 | function foo(): string |
function foo() |
| 标量类型提示 | function bar(int $id) |
function bar($id) |
| 短数组语法 | ['a', 'b'] |
✅ 5.4+ 已支持,可用 |
| JSON 中文不转义 | json_encode($d, JSON_UNESCAPED_UNICODE) |
✅ 5.4+ 已支持 |
核心原则:能用 isset() 就别用 ??,能用普通变量就别用 define() 存数组。
另外,老服务器的 SSL 证书可能没更新,cURL 请求 HTTPS 会报错。解决方案:
php
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
生产环境建议配置好 CA 证书后开启验证,但开发阶段先关了跑通再说。
六、部署步骤
-
在 DeepSeek 开放平台注册,创建 API Key
-
将三个文件上传到服务器同一目录: /your-project/ai/ ├── ai_config.php ← 填入你的 API Key ├── ai_helper.php └── ai_demo.html
-
确认 PHP 环境已开启
curl和openssl扩展:bashphp -m | grep -E "curl|openssl" -
浏览器访问
ai_demo.html,在页面顶部配置 API 地址(填ai_helper.php的完整 URL) -
点击"测试连接",成功后即可使用三个功能
部署清单:
- PHP 5.6+(5.4 也行,但不推荐)
- cURL 扩展已开启
- OpenSSL 扩展已开启
- 服务器可访问
api.deepseek.com(出网 HTTPS) -
ai_config.php中的 API Key 已替换为真实密钥
七、成本估算
以一个中型内容平台为例:
| 场景 | 日调用量 | 平均 Token | 月成本(平峰价) |
|---|---|---|---|
| 错别字检查(编辑器集成) | 500 次 | ~800 | ≈ 18 元 |
| 文案解读(运营审核) | 50 次 | ~1500 | ≈ 4 元 |
| 智能问答(用户咨询) | 200 次 | ~1200 | ≈ 15 元 |
| 合计 | ≈ 37 元/月 |
DeepSeek 高峰时段(工作日 9:00-12:00、14:00-18:00)价格翻倍,非紧急任务可以错峰调用。
一个月三十几块钱,比请一个实习生还便宜,而且 7×24 在线。
八、安全注意事项
- API Key 只放后端 :密钥写在
ai_config.php中,前端永远拿不到。千万不要把 Key 写在 JS 里。 - 限制访问来源 :上线后把 CORS 的
*改成你的域名。 - 文本长度限制:已在代码中设置上限(chat 4000 字,其他 5000 字),防止恶意调用消耗 Token。
- 日志默认关闭 :调试时打开
$DS_LOG_ENABLED = true,上线后务必关闭,日志文件会记录请求内容。 - 配置文件保护 :建议把
ai_config.php放到 Web 根目录之外,或通过.htaccess禁止直接访问。
九、扩展思路
这套架构天然支持扩展:
- 接入其他模型 :改
$DS_API_URL和$DS_API_KEY,换成阿里云通义、智谱 GLM,代码几乎不用动(都是 OpenAI 兼容格式) - 流式输出 :把
stream改成true,前端用ReadableStream读取,打字机效果立刻有 - 批量处理 :循环调用
ds_call_api(),做批量文案审核或批量错别字扫描 - 接入富文本编辑器:在 TinyMCE / CKEditor 中集成错别字检查,实时标红提示
- 定时任务:用 cron + PHP CLI 模式批量处理数据库中的文案内容
写在最后
老系统不是不能加 AI,是怕一上来就 Composer + Laravel + Vue 全家桶。30 行 cURL + 一个 HTML 文件,半小时就能让老板看到效果。
DeepSeek 的 API 兼容 OpenAI 格式,迁移成本几乎为零。今天用 DeepSeek,明天想换通义千问,改两行配置的事。
完整源码文件:
ai_config.php--- 配置与辅助函数ai_helper.php--- 接口路由层ai_demo.html--- 前端交互页面
@漏刻有时