
在 tcpdf 中循环输出反序列化数组时,若仅在循环外调用一次 writehtml(),将导致只渲染最后一个元素;必须将 writehtml() 移入内层循环,确保每个数组项独立写入 pdf。
问题根源在于变量覆盖与 PDF 写入时机:原代码中 foreach 循环反复给 $f 赋值(如 3 → 7),但 writeHTML($f, ...) 仅执行一次,因此最终仅显示最后一次赋值的结果(即 7)。而浏览器中可能因 echo 或 print_r 实时输出,掩盖了该逻辑缺陷。
✅ 正确做法是:将 writeHTML() 放入 foreach 循环体内,对每个反序列化后的值单独渲染:
$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 (is_array($fine_typesR)) {
foreach ($fine_typesR as $fine_typet) {
// 推荐添加 HTML 包装以提升可读性(如换行或列表)
$html = '' . htmlspecialchars((string)$fine_typet) . '';
$pdf->writeHTML($html, true, false, false, false, '');
}
}
}? 关键改进说明:
- ✅ 使用预处理语句(mysqli_prepare)替代拼接 SQL,防止 SQL 注入;
- ✅ 添加 @unserialize() 抑制警告,并配合 is_array() 校验,避免反序列化失败导致空循环或错误;
- ✅ 对输出内容使用 htmlspecialchars() 转义,防止 HTML 注入或格式错乱;
- ✅ 为每个值包裹 并设置 margin,确保 PDF 中清晰分隔(TCPDF 对纯文本换行支持有限,结构化 HTML 更可靠);
- ❌ 避免在循环外累积字符串再一次性写入(如 $html .= ... 后 writeHTML()),因 TCPDF 的 writeHTML() 在连续调用时会自动追加内容,无需手动拼接。
? 额外建议:
若需输出为无序列表,可改用:$html = '
- ' . implode('
- ', array_map('htmlspecialchars', $fine_typesR)) . '
但注意:$fine_typesR 必须为一维数组,且含非空值。
综上,核心原则是——让每一次数据输出都对应一次 writeHTML() 调用,并始终校验数据有效性与安全性。










