You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PrestaShop PHP模块生成PDF时遇“Unable to find PDF file header”错误求助

PrestaShop PDF合并报错“Unable to find PDF file header”排查方案

核心问题:文件删除时机错误

你代码里在调用$pdf->setSourceFile($path)后立刻删除了文件,但PDF库(如TCPDF/FPDF)的importPage操作可能是懒加载逻辑——调用setSourceFile时仅读取文件头,实际页面内容读取是在importPage阶段。服务器文件I/O速度比本地慢,此时文件已被unlink删除,自然找不到PDF头。

修复:把文件删除操作移到PDF页面导入完成之后:

foreach ($order->export_invoice_url as $page=>$link) {
    // 用唯一文件名避免循环中文件覆盖冲突
    $path = __DIR__ . '/data/pdf_' . uniqid() . '.pdf';

    // 先获取远程PDF内容,增加错误判断
    $pdfContent = file_get_contents($link);
    if ($pdfContent === false) {
        error_log("Failed to fetch PDF from: " . $link);
        continue;
    }

    file_put_contents($path, $pdfContent);
    $pdf->setSourceFile($path);

    // 完成页面导入和添加后,再删除临时文件
    $tplIdx = $pdf->importPage(1);
    $pdf->AddPage();
    $pdf->useTemplate($tplIdx, 0, 0, null, null, true);

    unlink($path);
}

可能的其他问题及排查

1. file_get_contents获取的不是有效PDF内容

服务器环境与本地差异可能导致远程PDF获取失败,写入的是错误页面(如404、500的HTML)而非PDF:

  • 检查服务器PHP配置的allow_url_fopen是否开启(php.ini中设置为On),若禁用则改用CURL更可靠。
  • 验证$link在服务器上能否正常访问:通过SSH执行curl -I "你的PDF链接",查看返回的HTTP状态码是否为200,Content-Type是否为application/pdf。
  • 增加PDF内容校验:写入文件前检查内容开头是否是%PDF(PDF文件标准头),避免无效内容被处理:
    if (substr($pdfContent, 0, 4) !== '%PDF') {
        error_log("Invalid PDF content from: " . $link);
        continue;
    }
    

2. 临时文件竞争或权限细节

  • 循环复用同一个文件名pdf.pdf,可能前一次文件还未完全写入就被覆盖,导致内容不完整——改用uniqid()生成唯一文件名(如上述代码所示)。
  • 确认__DIR__/data目录权限:除读写权限外,需确保PHP进程对该目录有执行权限(通常设置为755),避免无法创建文件。

3. PDF库版本差异

本地和服务器使用的TCPDF/FPDF版本不一致,部分旧版本对文件读取逻辑有差异。可对比两边库版本,优先保持与本地一致的版本。

4. 改用CURL替代file_get_contents

若allow_url_fopen被禁用,或远程链接存在跳转、HTTPS证书问题,用CURL更稳定:

function fetchRemotePDF($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    // 生产环境建议配置可信证书,临时关闭SSL验证仅用于排查
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    $content = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200 || $content === false || substr($content, 0, 4) !== '%PDF') {
        return false;
    }
    return $content;
}

// 循环中调用
$pdfContent = fetchRemotePDF($link);
if (!$pdfContent) {
    error_log("Skipping invalid PDF: " . $link);
    continue;
}
file_put_contents($path, $pdfContent);

内容的提问来源于stack exchange,提问作者Sharkerz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 08:12:42