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

如何用Storage::putFile存储Guzzle Stream并解决hashName不存在报错

问题根因

call_user_func_array() expects parameter 1 to be a valid callback, class 'GuzzleHttp\Psr7\Stream' does not have a method 'hashName'

这个报错是因为Laravel的Storage::putFile()方法默认要求传入的第二个参数是Illuminate\Http\UploadedFile实例,该类内置了hashName()方法用于生成随机哈希文件名,而你传入的Guzzle Stream对象没有该方法,所以调用失败。

解决方案

方案1:使用Storage::put()方法直接存储流(推荐)

put方法原生支持传入PSR-7标准的流实例,你只需要自行指定存储路径和文件名即可,代码修改如下:

use Illuminate\Support\Str;

public function setCVAttribute($value) {
    if($value != null) {
        if(isset($this->attributes['cv']) && Storage::exists($this->attributes['cv'])) {
            Storage::delete($this->attributes['cv']);
        }
        // 可从邮件解析的附件元数据中获取原始后缀、mime类型,替换示例中的固定值
        $extension = 'pdf';
        $fileName = Str::random(40) . '.' . $extension;
        $path = 'cvs/' . $fileName;
        // 直接传入Guzzle Stream实例即可
        Storage::put($path, $value);
        $this->attributes['cv'] = $path;
    }
}

方案2:封装为UploadedFile实例适配putFile逻辑

如果业务需要保留putFile的自动命名逻辑,可以先把流写入临时文件再封装为UploadedFile实例:

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\File;

public function setCVAttribute($value) {
    if($value != null) {
        if(isset($this->attributes['cv']) && Storage::exists($this->attributes['cv'])) {
            Storage::delete($this->attributes['cv']);
        }
        // 生成临时文件存储流内容
        $tmpPath = tempnam(sys_get_temp_dir(), 'cv');
        file_put_contents($tmpPath, $value);
        // 实例化UploadedFile,mime类型可从附件元数据获取替换
        $uploadedFile = new UploadedFile($tmpPath, 'cv.pdf', 'application/pdf', null, true);
        $path = Storage::putFile('cvs', $uploadedFile);
        // 清理临时文件
        File::delete($tmpPath);
        $this->attributes['cv'] = $path;
    }
}

内容的提问来源于stack exchange,提问作者NicolasSC

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 16:00:03