需要在 Linux 伺服器上將網頁渲染為圖片或 PDF?wkhtmltox(基於 Qt WebKit 的 wkhtmltopdf/wkhtmltoimage)是經典解決方案。本文記錄在 CentOS 7 環境下完整編譯安裝 PHP wkhtmltox 擴展的流程,並提供現代化替代方案建議。
# 安裝編譯工具與 Qt 相依套件
yum install -y gcc gcc-c++ make openssl-devel libX11-devel libXext-devel \
libXrender-devel fontconfig-devel freetype-devel libpng-devel \
php-devel php-pear wget xz tar
# 進入暫存目錄 cd /usr/local/src # 下載穩定版(官網已遷移至 GitHub Releases) wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox-0.12.6-1.centos7.x86_64.rpm # 直接用 RPM 安裝(含二進制、庫檔、字型) rpm -ivh wkhtmltox-0.12.6-1.centos7.x86_64.rpm # 驗證安裝 wkhtmltoimage --version # 輸出:wkhtmltoimage 0.12.6 (with patched qt)> 提示: 官方提供預編譯 RPM/DEB,強烈建議優先使用套件管理器安裝,避免手動編譯 Qt 的漫長等待與相依地獄。
# 下載擴展原始碼 cd /usr/local/src git clone https://github.com/mreiferson/php-wkhtmltox.git cd php-wkhtmltox # 編譯安裝(確認 phpize 路徑) /usr/bin/phpize ./configure --with-php-config=/usr/bin/php-config make && make install # 輸出類似:Installing shared extensions: /usr/lib64/php/modules/
# 查詢 php.ini 位置 php --ini # 新增擴展載入設定(建議建立獨立 ini 檔) echo "extension=phpwkhtmltox.so" > /etc/php.d/50-wkhtmltox.ini # 重啟 PHP-FPM systemctl restart php-fpm # 驗證模組載入 php -m | grep wkhtmltox
<?php
// 簡單測試:將網頁截圖儲存為 JPG
$result = wkhtmltox_convert('image', [
'out' => '/tmp/test_163.jpg',
'in' => 'https://www.163.com/',
// 可選參數
'fmt' => 'jpg',
'quality' => 85,
'width' => 1366,
'height' => 768,
'disableJavascript' => false,
'loadErrorHandling' => 'ignore',
]);
if ($result === true) {
echo "截圖成功!檔案大小:" . filesize('/tmp/test_163.jpg') . " bytes";
} else {
echo "截圖失敗,錯誤代碼:$result";
}
?>
| 問題 | 原因與解決 |
|---|---|
| 截圖空白/白屏 | 目標頁面需 JavaScript 渲染,確認 disableJavascript=false;或增加 windowStatus: 'ready' 等待條件 |
| 中文字體缺失/方塊字 | 安裝中文字體:yum install -y wqy-zenhei-fonts 或複製 Microsoft YaHei 至 /usr/share/fonts/ 後執行 fc-cache -fv |
| SSL 憑證驗證失敗 | 加入參數 'ignoreSslErrors' => true, 'sslProtocol' => 'TLSv1_2' |
| 權限拒絕 Permission denied | 確認 PHP-FPM 執行用戶對輸出目錄有寫入權限;SELinux 需設定 setsebool -P httpd_execmem 1 |
| 記憶體不足 OOM | 大頁面渲染需大量記憶體,調整 php.ini memory_limit 或拆分任務 |
wkhtmltox 基於已停止更新的 Qt WebKit,對現代 CSS (Flexbox/Grid)、JS (ES6+) 支援有限。新專案建議採用:
// Node.js 端 screenshot.js
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({args: ['--no-sandbox']});
const page = await browser.newPage();
await page.goto(process.argv[2], {waitUntil: 'networkidle2'});
await page.screenshot({path: process.argv[3], fullPage: true});
await browser.close();
})();
// PHP 呼叫
$url = 'https://example.com';
$output = '/tmp/screenshot_' . time() . '.png';
exec("node screenshot.js " . escapeshellarg($url) . " " . escapeshellarg($output));
echo file_exists($output) ? "成功" : "失敗";
exec("google-chrome-stable --headless --disable-gpu --screenshot={$output} --window-size=1366,768 " . escapeshellarg($url));
本文提供了 wkhtmltox 在 CentOS 7 上的完整安裝流程,適合維護舊專案。但鑑於 WebKit 內核老舊、Qt 依賴沉重、安全更新停止,強烈建議新專案採用 Chrome Headless / Puppeteer / Playwright 方案,支援現代 Web 標準、渲染保真度高、社群活躍且易於容器化部署。