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

Laravel 8 + Spatie MediaLibrary v10 生产环境生成响应式图片时依赖无法实例化的问题排查求助

Laravel 8 + Spatie MediaLibrary v10 生产环境生成响应式图片时依赖无法实例化的问题排查求助

各位开发者大佬,我现在遇到一个非常诡异的生产环境问题,想请大家帮忙分析排查:

我在 Laravel 8.0 搭配 Spatie\MediaLibrary v10 的项目中,尝试给接口上传的图片生成响应式版本,但生产环境一直抛出如下错误:

Target [Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\WidthCalculator] is not instantiable while building [Spatie\MediaLibrary\ResponsiveImages\ResponsiveImageGenerator]

本地开发环境完全正常,而且我已经确认生产和本地的PHP版本都是8.1,必要的依赖库也都安装完整。更奇怪的是,图片本身能正常保存到目录中,只是响应式图片的相关额外文件(比如不同尺寸的变体、占位SVG)生成不出来。

我的代码结构说明

为了减少重复代码,我封装了一个SaveImagesClass,它的构造函数依赖ModelEventClass——这个类承载了从控制器注入的匿名函数,用来处理不同模型的保存逻辑(项目里有11个不同模块,都需要处理带图/不带图的数据保存,所以想做统一封装)。

相关服务绑定是在AppServiceProvider中完成的:

$this->app->bind(SaveImagesInterface::class, SaveImagesClass::class);

$this->app->bind(SaveImagesClass::class, function ($app) {
    return new SaveImagesClass($app->make(ModelEventClass::class));
});

SaveImagesClass核心代码:

class SaveImagesClass implements SaveImagesInterface {
    use ResponseJsonTrait;

    public function __construct(
        protected ModelEventClass $modelEventClass
    ) {}

    public function store(Request $request, array $data): array {
        try {
            $ids = [];
            $user_id = auth()->user()->id;
            foreach ($data as $key => $value) {
                if(!$this->modelEventClass->exists($value, $user_id)) {
                    $this->modelEventClass->insert($request, $value["data"], $chunk["image"]);
                    $ids[] = $value["data"]["id"];
                }
            }
            $msg = __("Saved");
            return $this->resultArray($msg, 200, $ids);
        } catch(\Exception $e) {
            $msg = $e->getMessage();
            return $this->resultArray($msg, 500, null, false);
        }
    }
}

ModelEventClass代码:

class ModelEventClass {
    public function __construct(
        protected Closure $insert_model_data,
        protected Closure $model_data_exists
    ) {}

    public function insert(Request $request, array $data, ?string $image_name): void {
        $local = Closure::fromCallable($this->insert_model_data);
        $local($request, $data, $image_name);
    }

    public function exists(array $value, int $user_id): bool {
        $local = Closure::fromCallable($this->model_data_exists);
        return $local($value, $user_id);
    }
}

控制器中的调用逻辑(注入匿名函数处理模型和图片):

public function __construct() {
    $this->saveImagesClass = new SaveImagesClass(new ModelEventClass(
        function(Request $request, array $data, ?string $image_name): void {
            $create = Model::create($data);
            if(isset($image_name)) {
                $uuid = (string) Str::uuid();
                $create->addMediaFromRequest($image_name)
                    ->setName($uuid)
                    ->withResponsiveImages()  // *就是这行代码在生产环境触发报错*
                    ->toMediaCollection();
            }
        },
        function(array $value, int $user_id): bool {
            return Model::where("user_id", "=", $user_id)
                ->where("qr_id", "=", $value["qr_id"])
                ->where("date", "=", $value["date"])
                ->exists();
        }
    ));
}

我已经完成的排查步骤

  1. 移除封装直接在控制器保存:把图片保存逻辑直接写到控制器中,去掉SaveImagesClass和ModelEventClass的封装层,结果错误依然存在。
  2. 手动绑定WidthCalculator依赖:查资料发现MediaLibrary有自带的服务提供者,里面注册了相关服务,不知道为什么生产环境没自动注册,于是我在AppServiceProvider的register方法中添加:
    $this->app->bind(WidthCalculator::class, config('media-library.responsive_images.width_calculator'));
    
    这行代码解决了WidthCalculator的实例化错误,但又出现新的错误:

    Target [Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\TinyPlaceholderGenerator] is not instantiable while building [Spatie\MediaLibrary\ResponsiveImages\ResponsiveImageGenerator]

  3. 手动绑定占位生成器依赖:接着把占位生成器的绑定也添加到AppServiceProvider中,这次响应式图片终于能生成了,但又出现新错误:

    No hint path defined for [media-library]

  4. 手动加载视图路径:尝试在AppServiceProvider的boot方法中添加:
    $this->loadViewsFrom(__DIR__.'/../resources/views', 'media-library');
    
    结果又抛出新的错误:

    View [placeholderSvg] not found

现在彻底卡在这里了,明明本地环境一切正常,生产环境的配置和依赖都和本地对齐了,为什么会出现这些连锁问题?有没有大佬能指点一下方向?

备注:内容来源于stack exchange,提问作者Hmerman6006

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 09:39:30