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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 22:47:06