跳转到内容

compat-legacy 故障排查

大多数迁移问题都归入少数几种模式。以下每一项都会列出症状、原因和修复方法。当你不确定某个特定方法时,请参阅 /integrations/tcpdf-compat/method-coverage/ 以及仓库中的权威对照表 docs/TCPDF_COVERAGE.md

进程过去会在 PDF 错误时停止;现在会抛出异常

标题为“进程过去会在 PDF 错误时停止;现在会抛出异常”的章节

症状。 之前在渲染失败时会停止的代码,现在会抛出未捕获的 RuntimeException,导致该请求或任务暴露错误。

原因。 旧版 TCPDF 的 Error() 会调用 die()。适配器改为抛出 RuntimeException,这是有意设计,目的是让失败可被观察到。

修复。 将渲染入口点包在 try/catch 中,并将异常映射到你的错误契约。请勿恢复 die() 的行为。请参阅 /integrations/tcpdf-compat/production-usage/ § 失败处理。

症状。 你已经启用 LegacyBootstrap::enableAliases(),但输出看起来仍像旧版 TCPDF,或者行为没有变化。

原因。 只有在尚未存在同名类时,enableAliases() 才会注册别名。如果 tecnickcom/tcpdf 仍可被自动加载,并且它的 \TCPDF 先加载,别名就会被跳过,你的代码也会继续使用旧版 TCPDF。

修复。 在迁移期间,请优先在各文件中使用显式导入(use NextPDF\Compat\Tcpdf\TCPDF;),确保每个调用处都没有歧义。审计通过后,即可移除 tecnickcom/tcpdf(请参阅 /integrations/tcpdf-compat/migration/ 阶段 5)。请勿在同一个进程中同时运行两套库并启用全局别名。

某个方法「能运作」,但我传入的参数被忽略了

标题为“某个方法「能运作」,但我传入的参数被忽略了”的章节

症状。 调用成功并生成了 PDF,但你传入的某个选项(图片链接、对齐、DPI、书签颜色……)没有生效。

原因。 该方法属于静默忽略集合。它为了保持源码兼容性而接受该参数,随后将其丢弃。这是已有文档说明的行为,并非缺陷,请参阅 /integrations/tcpdf-compat/method-coverage/ §2。

修复。 运行严格模式审计,找出每一个这类调用:

examples/troubleshoot-strict.php
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\Exception\TcpdfNotImplementedException;
use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF();
$pdf->setStrictMode(true);
$pdf->AddPage();
$pdf->SetFont('helvetica', '', 12);
try {
$pdf->Image('logo.png', 10, 10, 50, 0, '', 'https://example.com');
} catch (TcpdfNotImplementedException $e) {
// Message lists every ignored parameter and a migration hint.
echo $e->getMessage(), "\n";
}

然后删除该参数,或改用现代 API 重新表达($pdf->getDocument()),如 /integrations/tcpdf-compat/migration/ 阶段 4 所示。

症状。 依赖 MultiCell() 返回值进行分支判断的代码(例如用来计算已使用的高度或行数),行为不正确。

原因。 适配器的 MultiCell() 返回的是兼容性占位值 1,而不是实际渲染的 cell/line 数量。Write() 同样返回 0

修复。 请勿依赖这些返回值进行分支判断。如果你需要渲染后的高度,请改用 getStringHeight() / getNumLines() 计算,或将该逻辑迁移到现代 API。

setPDFVersion('1.4') 并未生成 PDF 1.4 文件

标题为“setPDFVersion('1.4') 并未生成 PDF 1.4 文件”的章节

症状。 你请求了较旧的 PDF 版本,但输出仍是 PDF 2.0。

原因。 输出永远是 PDF 2.0(ISO 32000-2)。setPDFVersion() 属于不适用集合;适配器会发出通知并继续运行。

修复。 移除该调用。如果某个下游使用方需要较旧的 PDF 版本,请另行解决该使用方的约束;适配器无法降版输出。

setSignature() 没有任何作用——PDF 并未被签名

标题为“setSignature() 没有任何作用——PDF 并未被签名”的章节

症状。 你以证书调用了 setSignature();输出的 PDF 却没有签名。

原因。 通过此适配器调用时,setSignature() 在核心引擎上并未实现。在默认模式下它是无操作;在严格模式下则会抛出异常。

修复。 签名需要商业版 NextPDF 以及现代签名 API。请参阅 /integrations/tcpdf-compat/security-and-operations/ § 数字签名。请勿期望旧版的 setSignature() 调用能签名任何内容。

Output() 损坏了我的 HTTP 响应或 worker 输出

标题为“Output() 损坏了我的 HTTP 响应或 worker 输出”的章节

症状。 HTTP 响应中出现二进制乱码,或 worker 日志被 PDF 字节污染。

原因。 你在自行控制响应的场景中,使用了会写入输出路径的输出目标(I/D)。适配器并不会像旧版 TCPDF 那样将内容回显到你的缓冲区,但 I/D 仍会驱动引擎输出。

修复。 在你自行控制的 worker 与处理器中,使用 Output($path, 'F') 写入文件,或使用 Output($name, 'S') 获取字节并自行输出。目标映射(不区分大小写、已去除空白)已在 tests/Unit/Compat/Tcpdf/Bridge/OutputBridgeTest.php 中通过断言验证:

代码返回副作用
SPDF 字节(%PDF…
F空字符串写入文件
Ebase64 MIME 主体
FI / FD空字符串写入文件,然后引擎输出
I / D / 未知空字符串引擎输出(内联/下载)

症状。 比较原始 PDF 字节的快照测试大量失败。

原因。 该引擎是一套独立的 PDF 2.0 实现。对于委托的方法,可见输出是兼容的,但字节会有所不同。这属于预期行为。

修复。 重新建立基线,改为断言渲染后的内容(提取的文本)、结构(页数、页面尺寸),或执行一次冒烟检查(str_starts_with($bytes, '%PDF'))。请参阅 /integrations/tcpdf-compat/migration/ 阶段 4。

症状。 你通过常量设置的自定义路径或默认值未生效。

原因。 只有在常量尚未定义时,适配器才会自动定义它,而且是在首次构造时进行。如果你的 define() 在首个适配器构造之后才运行,则适配器的默认值已经生效。

修复。 在你的引导程序中、创建任何适配器实例之前,定义所有自定义 K_* / PDF_* 常量。请参阅 /integrations/tcpdf-compat/configuration/ § 配置解析顺序。

症状。 在依赖更新后,构造失败或行为异常。

原因。 适配器需要 nextpdf/core ^3.0。如果解析出的核心版本超出该范围,则不受支持。

修复。 运行 composer show nextpdf/core,并将引擎固定到 ^3.0。请参阅 /integrations/tcpdf-compat/install/ § 验证引擎版本。

问题在哪里查看
方法 X 在这里实际做了什么?/integrations/tcpdf-compat/method-coverage/、docs/TCPDF_COVERAGE.md
我的哪些调用会丢失参数?严格模式审计(本页;/integrations/tcpdf-compat/migration/)
为什么进程没有在出错时停止?/integrations/tcpdf-compat/security-and-operations/ § 强化行为
为什么输出未被签名 / 不是 PDF/A?/integrations/tcpdf-compat/security-and-operations/
别名与显式导入的冲突本页;/integrations/tcpdf-compat/boot-and-discovery/
  • /integrations/tcpdf-compat/migration/ —— 分阶段迁移可以避免上述大多数问题
  • /integrations/tcpdf-compat/method-coverage/ —— 逐方法行为参考
  • /integrations/tcpdf-compat/boot-and-discovery/ —— 别名注册与冲突规避
  • docs/TCPDF_COVERAGE.md —— 权威覆盖对照表