
tcpdf 中无法显示反序列化数组所有值,是因为 `writehtml()` 被错误地置于循环外部,导致仅最后一次赋值的 `$f` 被输出;正确做法是将 `writehtml()` 移入 `foreach` 循环内部,确保每个数组元素独立渲染。
在使用 TCPDF 生成 PDF 报表时,若需展示从 MySQL 中读取并反序列化的 PHP 数组(如 serialize() 存储的多值字段),常见错误是逻辑结构错位:反序列化操作与 HTML 输出未一一对应。
原始代码的问题在于:
while($row22 = mysqli_fetch_assoc($resulty)){
$fine_typesR = unserialize($row22['fine_type']); // 每次覆盖,最终只保留最后一行的反序列结果
}
foreach ($fine_typesR as $fine_typet) {
$f = $fine_typet; // 逐个赋值,但未输出
}
$pdf->writeHTML($f, true, false, false, false, ''); // 仅输出最后一次循环的 $f → 单值这导致两个关键缺陷:
- while 循环中反复覆盖 $fine_typesR,实际只处理了最后一条数据库记录的反序列化结果;
- foreach 中虽遍历了数组,但 writeHTML() 在循环外执行,因此仅写入最后一个 $fine_typet。
✅ 正确写法应做到 “逐条读取 → 逐项反序列化 → 立即写入 PDF”,推荐结构如下:
$query1 = "SELECT * FROM fine_controls WHERE formid = ?";
$stmt = mysqli_prepare($link, $query1);
mysqli_stmt_bind_param($stmt, "s", $emp_id);
mysqli_stmt_execute($stmt);
$resulty = mysqli_stmt_get_result($stmt);
while ($row22 = mysqli_fetch_assoc($resulty)) {
$fine_typesR = @unserialize($row22['fine_type']);
// 安全检查:确保反序列化成功且为数组
if ($fine_typesR !== false && is_array($fine_typesR)) {
foreach ($fine_typesR as $fine_typet) {
// 可选:添加分隔符或换行提升可读性
$content = htmlspecialchars((string)$fine_typet, ENT_QUOTES, 'UTF-8');
$pdf->writeHTML("● {$content}", true, false, false, false, '');
}
} else {
$pdf->writeHTML("[Invalid serialized data]", true, false, false, false, '');
}
}? 关键改进说明:
- ✅ 使用 mysqli_prepare() 防止 SQL 注入(原代码存在严重安全风险);
- ✅ @unserialize() 加 @ 抑制警告,并配合 false 判断避免解析失败导致空数组;
- ✅ writeHTML() 紧贴 foreach 内部,确保每个值都生成独立 HTML 片段;
- ✅ 添加 htmlspecialchars() 防止 XSS(PDF 中嵌入用户数据时尤为重要);
- ✅ 使用 包裹 + CSS 样式,便于排版控制(TCPDF 支持基础内联样式)。
⚠️ 注意事项:
- TCPDF 的 writeHTML() 不支持全部 CSS,建议使用行内样式,避免 float、flex 等复杂布局;
- 若数组元素含 HTML 标签,请先 htmlspecialchars() 转义,再按需解码(如确需渲染富文本,需严格校验来源);
- 大量循环写入时,可考虑累积 HTML 字符串后单次 writeHTML(),但需注意内存与换行控制。
通过修正执行顺序与增强健壮性处理,即可稳定、安全地在 TCPDF 中完整呈现反序列化数组的所有条目。










