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

发送邮件时触发Call to a member function getRealPath() on string错误

解决Laravel发送邮件时Call to a member function getRealPath() on string错误

问题重现

发送邮件时触发错误,错误指向邮件类中调用getRealPath()的代码行:

->attach($this->data['resume']->getRealPath(),

相关代码如下:

控制器代码

public function store(CareerRequest $request)
{
    $requestData = $request->all();

    $filenameWithExt = $request->file('resume')->getClientOriginalName();
    $filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
    $extension = $request->file('resume')->getClientOriginalExtension();
    $fileNameToStore = $filename.'_'.time().'.'.$extension;
    $request->file('resume')->storeAs('candidateResume', $fileNameToStore);    
    $requestData["resume"] = $fileNameToStore ;

    Career::create($requestData);

    return redirect()->back();
}

邮件类(Mailable)代码

class CareerMail extends Mailable
{
    public $data;

    public function __construct($data)
    {
        $this->data = $data;
    }

    public function build()
    {
        return $this->subject('Career - '. $this->data->subject)
                    ->view('emails.career')
                    ->attach($this->data['resume']->getRealPath(),
                [
                    'as' => $this->data['resume']->getClientOriginalName(),
                    'mime' => $this->data['resume']->getClientMimeType(),
                ]);
    }
}

错误原因

控制器中已经将上传的文件存储到服务器,并将**存储后的文件名(字符串)**赋值给$requestData["resume"]存入数据库。但邮件类中错误地将这个字符串当作UploadedFile对象,调用了只有文件对象才有的getRealPath()、getClientOriginalName()等方法,导致类型错误。

解决方案

方案1:传递原始文件对象到邮件类(适用于存储文件后立即发邮件的场景)

如果在控制器存储文件后需要立即发送邮件,可以直接将原始的UploadedFile对象传递给邮件类,同时保留存储文件名到数据库的逻辑:

修改控制器代码:

public function store(CareerRequest $request)
{
    $requestData = $request->all();

    $filenameWithExt = $request->file('resume')->getClientOriginalName();
    $filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
    $extension = $request->file('resume')->getClientOriginalExtension();
    $fileNameToStore = $filename.'_'.time().'.'.$extension;
    $request->file('resume')->storeAs('candidateResume', $fileNameToStore);    
    $requestData["resume"] = $fileNameToStore ;

    Career::create($requestData);

    // 传递原始文件对象到邮件类
    Mail::to('recipient@example.com')->send(new CareerMail([
        'subject' => $requestData['subject'],
        'resume' => $request->file('resume')
    ]));

    return redirect()->back();
}

邮件类代码无需修改,此时$this->data['resume']是UploadedFile对象,可以正常调用相关方法。

方案2:从存储路径获取文件信息(适用于从数据库读取数据后发邮件的场景)

如果是从数据库读取已存储的记录来发送邮件,需要通过存储的文件名获取文件的真实路径和MIME类型,同时建议存储原始文件名到数据库以优化邮件附件显示:

步骤1:修改控制器,存储原始文件名到数据库

public function store(CareerRequest $request)
{
    $requestData = $request->all();

    $filenameWithExt = $request->file('resume')->getClientOriginalName();
    $filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
    $extension = $request->file('resume')->getClientOriginalExtension();
    $fileNameToStore = $filename.'_'.time().'.'.$extension;
    $request->file('resume')->storeAs('candidateResume', $fileNameToStore);    

    // 新增存储原始文件名
    $requestData["resume"] = $fileNameToStore ;
    $requestData["resume_original_name"] = $filenameWithExt;

    Career::create($requestData);

    return redirect()->back();
}

步骤2:修改邮件类,通过文件名获取文件信息

class CareerMail extends Mailable
{
    public $data;

    public function __construct($data)
    {
        $this->data = $data;
    }

    public function build()
    {
        $filePath = storage_path('app/candidateResume/' . $this->data['resume']);
        $mimeType = \Illuminate\Support\Facades\Storage::mimeType('candidateResume/' . $this->data['resume']);

        return $this->subject('Career - '. $this->data->subject)
                    ->view('emails.career')
                    ->attach($filePath, [
                        'as' => $this->data['resume_original_name'],
                        'mime' => $mimeType,
                    ]);
    }
}

这样就能正确获取文件的真实路径和相关信息,避免类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 13:01:11