Laravel Mailer如何传递表单提交来源页URL并解决报错
问题根因
你遇到的Function name must be a string报错、以及邮件视图拿不到来源页标识,是3个核心问题叠加导致的:
Mail::send()传参错误:Laravel中Mail::send()仅接受3个参数,依次为「视图模板路径」、「传给视图的参数数组」、「邮件配置闭包」。你额外把$currentPage作为第三个参数传入,框架会将该位置的参数识别为回调函数尝试执行,字符串无法作为函数调用,直接触发报错。- 表单隐藏域位置错误:存放来源页标识的
hidden输入框写在了<form>标签外部,表单提交时根本不会携带这个字段,后端拿不到有效值。 - 变量未传入视图:你没有把来源页标识合并到传给邮件视图的参数数组中,视图自然无法读取对应值。另外你把页面标识塞到了
returnPath()方法里,这个方法是配置邮件退信地址的,和传视图参数没有任何关系。
修正步骤
1. 修正表单代码
把隐藏的来源页字段移动到<form>标签内部,同时补上Laravel POST路由必需的CSRF令牌,修正旧值绑定的字段名错误:
<form method="POST" action="/sendEmail"> {{-- 隐藏域移到form标签内部 --}} <input type="hidden" name="source_page" value="{{ substr(strrchr(url()->current(),'/'),1) }}"> @csrf {{-- 不加CSRF令牌会直接报419页面过期错误 --}} <label for="name">Name</label> <input type="text" name="name" id="name" value="{{ old('name') }}" /> <label for="email">Email</label> <input type="email" name="email" id="email" value ="{{ old('email') }}"/> <label for="message">Message</label> {{-- 原代码old()绑定的字段名和实际name属性不一致,修正为body --}} <textarea name="body" id="message" rows="5">{{ old('body') }}</textarea> <button class="primary">Submit</button> </form>
更安全的优化:不建议通过前端隐藏域传来源页,用户可以通过浏览器调试工具随意篡改这个字段值。可以直接在后端通过
$request->headers->get('referer')获取HTTP请求的来源地址,完全不需要前端传值,避免参数伪造。
2. 修正控制器代码
调整Mail::send()的传参结构,把来源页标识合并到传给视图的数组中,删除多余参数,去掉无意义的Request别名写法:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Mail; class ContactController extends Controller { public function store(Request $request) { // 校验参数,加上来源页的白名单校验,拦截非法值 $data = $request->validate([ 'name' => 'required|string|max:100', 'email' => 'required|email', 'body' => 'required|string', 'source_page' => 'required|string|in:home,about,products,contact' ]); // 【如果用后端安全取来源页的方案,替换上面的前端传值逻辑即可,不需要前端加hidden字段】 // $sourcePath = parse_url($request->headers->get('referer'), PHP_URL_PATH); // $data['source_page'] = trim($sourcePath, '/'); // Mail::send严格传3个参数,不要多传 Mail::send('emails.contact', $data, function($message) use ($data){ $message->to('abc@xyz.com') ->from($data['email'], $data['name']) ->replyTo($data['email'], $data['name']) // 删除returnPath里塞页面标识的错误写法,该字段仅用于配置退信邮箱 ->subject('新的联系表单提交'); }); return back()->with('status', '表单提交成功'); } }
3. 修正邮件Blade视图
Blade模板输出变量需要用{{ 变量名 }}语法,不要直接写原生PHP风格的变量:
<p>提交人姓名:{{ $name }}</p> <p>提交人邮箱:{{ $email }}</p> <p>提交内容:{{ $body }}</p> <p>表单来源页面:{{ $source_page }}</p>
调整完成后再提交表单,就不会再触发函数名相关报错,邮件视图中也能正常获取到home/about/products/contact的来源页标识。
内容的提问来源于stack exchange,提问作者CuteSako
相关产品推荐
相关产品推荐

