Laravel 9 dompdf生产环境图片间歇性加载异常求助
解决Laravel + dompdf生产环境图片间歇性加载失败问题
针对你遇到的「Apache重启后PDF图片正常,一段时间后出现Image not found or type unknown」问题,以下是针对性的排查和解决方案:
排查文件句柄泄漏
长时间运行后异常,大概率是PHP进程未正确释放文件资源导致句柄耗尽。将file_get_contents替换为手动资源管理,确保文件句柄被关闭:// 读取国家logo $path_country_logo = public_path('logos/' . config('app.country_logo')); $handle = fopen($path_country_logo, 'rb'); $data_country_logo = fread($handle, filesize($path_country_logo)); fclose($handle); // 手动释放资源 $extension_logo_country = pathinfo($path_country_logo, PATHINFO_EXTENSION); $country_logo = "data:image/$extension_logo_country;base64," . base64_encode($data_country_logo); // 应用logo同理处理 $path_app_logo = public_path('logos/' . config('app.app_logo')); $handle = fopen($path_app_logo, 'rb'); $data_app_logo = fread($handle, filesize($path_app_logo)); fclose($handle); $extension_logo_app = pathinfo($path_app_logo, PATHINFO_EXTENSION); $app_logo = "data:image/$extension_logo_app;base64," . base64_encode($data_app_logo);调整dompdf缓存与临时目录配置
dompdf的缓存或临时目录权限不足、资源堆积可能引发异常。指定可写的临时目录并禁用缓存:$pdf = PDF::setOptions([ 'isRemoteEnabled' => true, 'tempDir' => storage_path('app/dompdf/temp'), // 确保此目录存在且可写 'cache' => false, ])->loadView('layouts.report', [ 'country_logo' => $country_logo, 'app_logo' => $app_logo, ]);执行命令确保目录权限正确:
mkdir -p storage/app/dompdf/temp chown -R www-data:www-data storage/app/dompdf chmod -R 755 storage/app/dompdf修复env变量缓存问题
生产环境Laravel会缓存env变量,直接调用env()可能导致后续读取失效。先在config/app.php中添加配置项:return [ // ...其他配置 'country_logo' => env('COUNTRY_LOGO'), 'app_logo' => env('APP_LOGO'), ];控制器中用
config()替代env():$path_country_logo = public_path('logos/' . config('app.country_logo'));执行缓存配置命令:
php artisan config:cache限制Apache子进程生命周期
Apache worker进程长时间运行可能出现内存泄漏或资源耗尽。在Apache配置文件(httpd.conf或apache2.conf)中添加:MaxRequestPerChild 1000让每个子进程处理1000个请求后自动重启,释放资源。
检查系统层面权限与SELinux
确认图片目录权限持续有效:chown -R www-data:www-data public/logos chmod -R 755 public/logos如果服务器启用了SELinux,临时关闭测试:
setenforce 0若问题解决,执行以下命令添加SELinux规则:
semanage fcontext -a -t httpd_sys_content_t "/var/www/html/your-project/public/logos(/.*)?" restorecon -Rv /var/www/html/your-project/public/logos改用本地文件路径加载图片
尝试绕过base64编码,直接让dompdf读取本地文件:
控制器传递路径:$pdf = PDF::setOptions(['isRemoteEnabled' => true])->loadView('layouts.report', [ 'country_logo' => public_path('logos/' . config('app.country_logo')), 'app_logo' => public_path('logos/' . config('app.app_logo')), ]);Blade视图中使用
file://前缀:<img src="file://{{ $country_logo }}" class="logo_class"> <img src="file://{{ $app_logo }}" class="app_logo">
内容的提问来源于stack exchange,提问作者SAWADOGO SIDIKI
相关产品推荐
相关产品推荐

