phpwkhtmltopdf生成图片损坏问题:跨服务器复现求助
我之前也碰到过几乎一模一样的情况,结合你提到的环境(Ubuntu 14.04 + PHP 5,Debian 9也复现),可以从这几个方向逐步排查解决:
1. 先确认本地生成的图片是否完整
首先排除wkhtmltopdf本身的问题——既然CLI运行正常,那可以先让PHP把生成的图片保存到服务器本地,验证文件本身是否完好:
<?php require 'vendor/autoload.php'; $pdf = new \Mike42\WkHtmlToPdf\Pdf(); $pdf->addPage("<html><body>测试图片内容</body></html>"); // 保存到本地临时目录 $pdf->saveAs('/tmp/test-output.png'); ?>
然后登录服务器,用file /tmp/test-output.png检查文件类型,或者下载到本地直接打开。如果本地文件正常,那问题肯定出在输出到客户端的环节。
2. 检查HTTP头部与输出缓冲区
这是最常见的原因:PHP脚本可能输出了多余的空白字符(比如文件开头/结尾的空格、BOM头),或者HTTP Content-Type设置错误,导致浏览器无法正确解析图片。
解决办法是在输出图片前清空所有缓冲区,并设置正确的响应头:
<?php require 'vendor/autoload.php'; // 清空所有输出缓冲区,避免多余字符污染图片数据 ob_clean(); // 根据wkhtmltopdf生成的图片格式设置Content-Type(png/jpeg等) header('Content-Type: image/png'); // 如果是下载需求,加上这个头 // header('Content-Disposition: attachment; filename="generated-image.png"'); $pdf = new \Mike42\WkHtmlToPdf\Pdf(); $pdf->addPage("<html><body>测试内容</body></html>"); // 直接输出图片二进制数据 echo $pdf->getImageData(); // 终止脚本,避免后续输出 exit; ?>
重点注意ob_clean()的使用——它会清空之前所有未发送的输出内容,很多时候就是这些看不见的空白导致图片损坏。
3. 确认phpwkhtmltopdf版本兼容PHP 5
Ubuntu 14.04的PHP 5已经比较老旧,而phpwkhtmltopdf的2.x版本开始要求PHP 7.0+。你需要检查composer依赖里的版本:
打开composer.json,确认mike42/wkhtmltopdf的版本是1.x系列(比如^1.4),如果是2.x版本,降级到兼容PHP 5的版本即可:
composer require mike42/wkhtmltopdf:^1.4
4. 排查PHP环境的输出配置
有些服务器的PHP配置里,output_buffering可能开启但有异常,或者zlib.output_compression开启导致二进制数据被压缩损坏。可以在脚本开头临时关闭压缩:
ini_set('zlib.output_compression', 'Off');
按照这个顺序排查,大概率能解决图片损坏的问题。
内容的提问来源于stack exchange,提问作者user9708574

