
本文详解如何在 php 中安全读取、解析、追加并写回 json 格式数据到 mysql 字段,涵盖 mysqli 预处理、json 编解码、数组动态追加等核心操作,并规避原始代码中的 sql 注入与过时扩展风险。
在 PHP 与 MySQL 开发中,将结构化数据(如用户列表)以 JSON 字符串形式存储在单个字段(如 uyeler)是一种常见做法。但直接拼接字符串更新 JSON 内容极易导致格式损坏(如缺失方括号、引号错乱)或安全漏洞。以下为生产就绪型实现方案,基于现代 PHP 实践重构原问题代码。
✅ 正确流程:读 → 解析 → 追加 → 编码 → 安全写入
首先,*必须弃用已废弃且不安全的 `mysql_函数**(PHP 7.0+ 已完全移除)。推荐使用mysqli(面向对象方式)或PDO。本例采用mysqli` 并启用预处理语句,彻底防止 SQL 注入:
connect_error) {
die("连接失败: " . $vtbaglan->connect_error);
}
// 2. 查询当前记录(注意:使用 WHERE id = ? 预处理更佳,此处简化示例)
$sorgum = $vtbaglan->query("SELECT id, uyeler FROM birlikler WHERE id = 1");
if (!$sorgum || $sorgum->num_rows === 0) {
die("未找到 ID=1 的记录");
}
$sorgu = $sorgum->fetch_assoc();
// 3. 解析现有 JSON 数据(true 参数返回关联数组,便于操作)
$uyesim = json_decode($sorgu['uyeler'], true);
if (json_last_error() !== JSON_ERROR_NONE) {
die("JSON 解析失败: " . json_last_error_msg());
}
// 4. 处理表单提交(追加新成员)
if (isset($_POST["verigir"])) {
// 输入过滤(基础防护)
$kullaniciadi = filter_input(INPUT_POST, 'kullaniciadi', FILTER_SANITIZE_STRING);
$rutbe = filter_input(INPUT_POST, 'rutbe', FILTER_SANITIZE_STRING);
$karakteradi = filter_input(INPUT_POST, 'kadi', FILTER_SANITIZE_STRING);
// 验证必填项
if (empty($kullaniciadi) || empty($rutbe) || empty($karakteradi)) {
echo "所有字段均为必填项!
";
} else {
// 构建新成员数组并追加到现有数组
$yeniUye = [
'kullanici' => $kullaniciadi,
'rutbe' => $rutbe,
'karakteradi' => $karakteradi
];
$uyesim[] = $yeniUye; // 关键:动态追加,自动维护 JSON 数组结构
// 5. 安全更新:使用预处理语句绑定 JSON 字符串
$stmt = $vtbaglan->prepare("UPDATE birlikler SET uyeler = ? WHERE id = ?");
$jsonString = json_encode($uyesim, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$stmt->bind_param('si', $jsonString, $sorgu['id']);
if ($stmt->execute()) {
echo "✅ 成员添加成功!
";
// 刷新 $uyesim 确保后续显示最新数据
$uyesim = json_decode($jsonString, true);
} else {
echo "❌ 更新失败: " . $stmt->error . "
";
}
$stmt->close();
}
}
?>
当前成员:
= htmlspecialchars($uye['kullanici']) ?> (等级: = htmlspecialchars($uye['rutbe']) ?>, 角色: = htmlspecialchars($uye['karakteradi']) ?>)
暂无成员
⚠️ 关键注意事项
- 绝不拼接 SQL 字符串:原代码 $uyelerim,$arrim 直接拼接会导致 JSON 格式崩溃(如 [{...}]{...}),且存在严重 SQL 注入风险。
- 始终验证 JSON 解析结果:json_decode() 可能返回 null(如空字符串或非法 JSON),需用 json_last_error() 检查。
- 输入过滤与输出转义:使用 filter_input() 过滤输入,htmlspecialchars() 防止 XSS 输出。
- JSON 编码选项优化:JSON_UNESCAPED_UNICODE 保留中文,JSON_UNESCAPED_SLASHES 避免冗余转义。
- MySQL 字段类型建议:uyeler 字段应设为 JSON 类型(MySQL 5.7+)或 LONGTEXT(兼容旧版),并确保长度足够(如 TEXT 可能不足)。
? 总结
将 JSON 数据存于数据库字段并非反模式,但必须遵循“解析→操作→编码→安全写入”四步法。结合 mysqli 预处理与严格的数据校验,即可稳健支撑动态增删场景。随着业务增长,若查询需求变复杂(如按成员名搜索),建议迁移到规范化关系表结构——但对简单列表管理,此方案简洁高效、易于维护。
立即学习“PHP免费学习笔记(深入)”;











