PHP 7.4 调用 Gemini API 实现多轮对话需手动管理上下文:将用户与模型消息存入 $_SESSION 或数据库,每次请求时完整拼接 contents 数组并传入,且须控制长度防截断。

PHP 7.4 本身无法直接调用 Gemini 的网页界面或侧边栏功能,它只能通过 Gemini API(即 Google AI Studio 提供的 generativeai REST API 或 SDK) 实现多轮对话。而 Gemini 官方 API 不自动保存对话历史——历史记录必须由你(开发者)在 PHP 后端显式管理、拼接并传入每次请求。
关键不是“Gemini 记住”,而是“你让 Gemini 看到完整上下文”。
一、用 ChatSession(推荐,但需注意版本)
Gemini 官方 SDK(如 Python 的 google.generativeai)提供了 ChatSession 类,能自动维护消息历史。
⚠️ 但截至 2026 年,Google 官方尚未发布正式支持 PHP 的 Gemini SDK。所以 PHP 7.4 必须使用 纯 HTTP 请求方式(REST API),自行构造 contents 数组来模拟多轮。
二、PHP 中手动拼接历史消息(核心做法)
每次请求 Gemini API 时,POST /v1beta/models/gemini-1.5-flash:generateContent 的请求体中,contents 字段是一个按时间顺序排列的消息数组,格式为:
{
"contents": [
{"role": "user", "parts": [{"text": "你好,请帮我写一个PHP连接MySQL的示例"}]},
{"role": "model", "parts": [{"text": "当然可以,以下是使用mysqli的示例代码……"}]},
{"role": "user", "parts": [{"text": "改成PDO写法"}]}
]
}✅ 在 PHP 中你需要:
立即学习“PHP免费学习笔记(深入)”;
- 把每轮用户提问和模型回复存进一个数组(例如
$_SESSION['gemini_history']或数据库); - 每次新提问前,把这个数组完整塞进
contents; - 发送请求后,把本次 AI 的回复追加进该数组,供下一轮使用。
示例片段(简化):
// 启动 session(确保已开启)
session_start();
if (!isset($_SESSION['gemini_history'])) {
$_SESSION['gemini_history'] = [];
}
// 当前用户输入
$userInput = $_POST['message'] ?? '';
if ($userInput) {
// 追加用户消息
$_SESSION['gemini_history'][] = ['role' => 'user', 'parts' => [['text' => $userInput]]];
// 构造请求体(含全部历史)
$payload = [
'contents' => $_SESSION['gemini_history']
];
// 调用 Gemini API(需替换 YOUR_API_KEY)
$ch = curl_init('https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=YOUR_API_KEY');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
$response = curl_exec($ch);
$data = json_decode($response, true);
if (isset($data['candidates'][0]['content']['parts'][0]['text'])) {
$aiReply = $data['candidates'][0]['content']['parts'][0]['text'];
// 追加AI回复到历史
$_SESSION['gemini_history'][] = ['role' => 'model', 'parts' => [['text' => $aiReply]]];
echo htmlspecialchars($aiReply);
}
}? 提示:
role只能是"user"或"model"(不是"assistant");parts是数组,即使只有一段文本也要包一层。
三、持久化保存历史(防刷新丢失)
$_SESSION 只在当前会话有效,关浏览器就清空。如需长期保存:
- 存入 MySQL 表(字段:
session_id,role,text,created_at,sort_order); - 或序列化后存 Redis(适合高频读写);
- 每次加载页面时,从数据库查出该会话全部历史,初始化
$_SESSION['gemini_history']。
四、避免上下文爆炸与截断
Gemini 对单次请求的 contents 总长度有限制(尤其免费 tier)。若历史过长:
- 只保留最近 N 轮(如最近 8 轮),丢弃更早的(可用
array_slice($history, -8)); - 或对早期消息做摘要压缩(用 Gemini 自己 summarize 前几轮,再替换进 history);
- 不要硬塞 30 轮——容易触发 400 错误或回答质量下降。
五、导出/备份对话(供人工归档)
PHP 后端可提供一个按钮,将当前 $_SESSION['gemini_history'] 导出为 JSON 文件:
header('Content-Type: application/json');
header('Content-Disposition: attachment; filename="gemini_chat_' . date('Ymd_His') . '.json"');
echo json_encode($_SESSION['gemini_history'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit;这样用户点击就能下载结构清晰、带角色标记的原始对话数据,后续可导入 Obsidian、Notion 或用于审计。
不复杂但容易忽略:历史不是 Gemini 的责任,是你 PHP 逻辑的责任。



















