Laravel提交表单时如何让Request Facade保留含空格的原字段名
我太懂这种被遗留数据库坑的感觉了——字段名带空格也就算了,Laravel还自动把请求里的空格转成下划线,每次手动写一堆字段赋值代码,简直要疯!别慌,给你几个实用的解决方案,从快速救急到一劳永逸都有:
解决方案1:手动转换请求字段名(快速临时方案)
如果只是个别控制器需要处理,直接在控制器里把请求数据的键名替换回来就行,不用挨个字段写赋值:
public function update(Request $request, $id) { // 把请求里的下划线键名转成空格格式 $formData = collect($request->all())->mapWithKeys(function ($value, $key) { return [str_replace('_', ' ', $key) => $value]; })->toArray(); $trainee = Trainee::findOrFail($id); $trainee->update($formData); return redirect()->back()->with('success', '更新成功'); }
这个方法简单直接,适合临时处理一两个页面的更新逻辑。
解决方案2:自定义Request类(全局优雅方案)
如果多个控制器、多个模型都要处理这类带空格的字段,最好自定义一个基础Request类,让所有需要的请求都继承它,一劳永逸解决键名转换问题:
首先创建一个基础请求类:
namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class BaseRequest extends FormRequest { public function all($keys = null) { // 先获取原始请求数据 $data = parent::all($keys); // 自动把下划线键名转成空格格式 return collect($data)->mapWithKeys(function ($value, $key) { return [str_replace('_', ' ', $key) => $value]; })->toArray(); } }
然后为你的Trainee更新请求创建一个专门的类,继承这个基础类:
namespace App\Http\Requests; class TraineeUpdateRequest extends BaseRequest { // 根据你的权限逻辑调整这个方法 public function authorize() { return true; } // 定义字段验证规则,这里写请求里的下划线字段名 public function rules() { return [ 'Family_Name' => 'required|string|max:255', 'Date_Of_Birth' => 'required|date', // 其他字段的验证规则... ]; } }
最后在控制器里使用这个自定义请求:
public function update(TraineeUpdateRequest $request, $id) { $trainee = Trainee::findOrFail($id); // 直接用$request->all()就行,已经自动转成带空格的键名了 $trainee->update($request->all()); return redirect()->back()->with('success', '学员信息更新成功'); }
这个方案适合项目里多个地方需要处理带空格字段的场景,一次配置终身受用。
解决方案3:模型层面处理属性映射(可选方案)
如果你更希望在模型层处理这个问题,不用动请求类,可以重写模型的setAttribute方法,让模型自动把下划线格式的属性转成带空格的数据库字段:
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Trainee extends Model { // 这里要写数据库里带空格的字段名 protected $fillable = ['Family Name', 'Date Of Birth', 'Email Address']; // 重写属性设置方法,自动转换键名 public function setAttribute($key, $value) { // 如果传入的键名是下划线格式,转成空格格式 $key = str_replace('_', ' ', $key); return parent::setAttribute($key, $value); } }
这样你在控制器里直接用$request->all()更新模型就行,模型会自动处理键名转换:
public function update(Request $request, $id) { $trainee = Trainee::findOrFail($id); $trainee->update($request->all()); return redirect()->back()->with('success', '更新成功'); }
这个方案适合不想修改请求逻辑,更倾向于在模型层封装数据库差异的场景。
为什么会出现这个问题?
简单说,Laravel的Request类为了符合PHP变量命名规范(PHP变量不能包含空格),会自动把请求字段名里的非字母数字字符(包括空格)替换成下划线,所以表单里的Family Name提交后,在$request里就变成了Family_Name,和数据库里的带空格字段自然匹配不上。
内容的提问来源于stack exchange,提问作者Lim Socheat
相关产品推荐
相关产品推荐

