根本原因是系统未安装wkhtmltoimage,php仅调用它而非自带截图能力;mac用brew install wkhtmltopdf,ubuntu/debian需单独装wkhtmltoimage包,windows须下载含exe的完整安装包。

wkhtmltoimage 安装失败或命令找不到
根本原因通常是系统没装 wkhtmltoimage,PHP 只是调用它,不是自带截图能力。Mac 用户用 brew install wkhtmltopdf(它会连带装 wkhtmltoimage);Ubuntu/Debian 要明确装 wkhtmltoimage 包,不是只装 wkhtmltopdf;Windows 用户得下带 wkhtmltoimage.exe 的完整安装包,不能只放个 DLL。
- 装完后在终端执行
wkhtmltoimage --version确认能运行 - PHP 里用
exec()或shell_exec()调用时,路径必须写全——比如/usr/local/bin/wkhtmltoimage,不能只写wkhtmltoimage(Web 服务器环境 PATH 通常不包含该路径) - apache 或 nginx 运行用户(如
www-data)可能没权限访问二进制文件或临时目录,建议用sudo -u www-data /usr/local/bin/wkhtmltoimage --version模拟验证
生成的截图空白、白屏或只截到导航栏
本质是 wkhtmltoimage 渲染时没等页面加载完、没执行 js、或被 CSP/跨域拦截。它默认不等待 JS 执行完毕,也不支持现代前端框架的 hydration 流程。
- 加
--javascript-delay 2000强制等 2 秒,比--load-Error-handling ignore更管用 - 避免截图含
file://协议的本地 HTML——它不支持读取本地资源,必须走 http(哪怕用http://localhost) - 如果目标页有登录态或 cookie,得手动传
--cookie参数,否则就是未登录状态下的空壳页 - 截图宽度设太小(如
--width 320)会导致响应式页面折叠成 hamburger 菜单,看起来像“只截到导航栏”
PHP 调用时超时、返回空或报错 “exit code 1”
wkhtmltoimage 是外部进程,PHP 默认 max_execution_time 常为 30 秒,但渲染复杂页面(尤其带图表、字体、远程图片)很容易超时;exit code 1 一般代表渲染失败,不是 PHP 报错。
- 调用前加
set_time_limit(120),别依赖 php.ini 全局设置 - 用
exec($cmd . ' 2>&1', $output, $returnCode)捕获完整错误输出,$output里常有关键线索,比如QXcbConnection: Could not connect to display(linux 无头环境缺 Xvfb) - 生产环境务必加
--no-stop-slow-scripts和--javascript-delay,否则 JS 卡住就一直挂起 - 输出路径要确保 Web 进程有写权限,且目录存在——
wkhtmltoimage不会自动建父级目录
中文乱码、字体缺失或截图模糊
wkhtmltoimage 底层用 qt webkit,对中文字体支持弱,默认不加载系统字体,也容易因缩放导致像素模糊。
立即学习“PHP免费学习笔记(深入)”;
- Linux 服务器必须装中文字体,如
fonts-wqy-zenhei(Debian)或fontconfig+wqy-microhei(centos),然后运行fc-cache -fv - 加参数
--encoding utf-8 --quality 100 --format png,避免 JPEG 压缩糊字;PNG 比 JPEG 更适合文字截图 - 别用
--zoom放大,改用--width和--height配合--crop-h/--crop-w精确控制可视区域 - 如果页面用了 Web Font(如 Google Fonts),确保网络可达,或提前下载字体并用
@font-face本地引用
真正卡住的地方往往不是 PHP 代码怎么写,而是 wkhtmltoimage 在目标环境里能不能稳定拉起浏览器内核、有没有权限读网络和字体、以及前端页面本身是否“可被服务端渲染工具理解”。调试时先抛开 PHP,直接在 shell 里跑通命令,再一层层加 PHP 封装。