Laravel中AJAX无法保存数据,控制器报$query未定义错误
问题排查与修复方案
核心问题分析
你遇到的无法保存数据+$query未定义错误,本质是控制器中未从请求对象获取字段值,导致$fname、$lname等变量未定义,代码执行到赋值阶段就抛出错误,无法走到save()步骤。同时还有模型批量赋值、CSRF验证等潜在问题需要处理。
1. 修复控制器变量未定义问题
修改save方法,从$request对象中读取所有表单字段值,替换原有的未定义变量:
<?php namespace App\Http\Controllers; use Haruncpi\LaravelIdGenerator\IdGenerator; use Illuminate\Http\Request; use App\Models\Patient; use Illuminate\Support\Facades\Validator; class Helpercontroller extends Controller { public function save(Request $request) { // 完善验证规则,覆盖所有必填字段 $validator = Validator::make($request->all(), [ 'cnic' => 'required|unique:patients', 'fname' => 'required', 'gender' => 'required', 'contactno' => 'required', // 可根据需求添加其他字段的验证规则,比如lname、age等 ]); if ($validator->fails()) { return response()->json(['success' => false, 'errors' => $validator->errors()->all()]); } // 注意:IdGenerator::generate已返回唯一递增ID,无需额外+1(避免ID重复) $patientid = IdGenerator::generate(['table' => 'patients', 'length' => 5, 'prefix' => '22']); // 从请求中读取字段并赋值 $patient = new Patient(); $patient->patientid = $patientid; $patient->fname = $request->fname; $patient->lname = $request->lname; $patient->cnic = $request->cnic; $patient->contactno = $request->contactno; $patient->gender = $request->gender; $patient->age = $request->age; $patient->dob = $request->dob; $patient->city = $request->city; $patient->address = $request->address; $patient->husbandname = $request->husbandname; $patient->fathername = $request->fathername; $patient->bloodgroup = $request->bloodgroup; $patient->maritalstatus = $request->maritalstatus; $patient->save(); return response()->json(['success' => true, 'patients' => $patient]); } }
2. 配置模型批量赋值白名单
Laravel默认阻止批量赋值,需在Patient模型中声明允许赋值的字段:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Patient extends Model { protected $table = 'patients'; // 若表名不是复数形式,需手动指定 protected $fillable = [ 'patientid', 'fname', 'lname', 'cnic', 'contactno', 'gender', 'age', 'dob', 'city', 'address', 'husbandname', 'fathername', 'bloodgroup', 'maritalstatus' ]; }
3. 确保AJAX请求的CSRF验证通过
Laravel默认验证POST请求的CSRF令牌,二选一即可:
方式1:表单内添加CSRF令牌
在registrationform表单中加入:@csrf这样
$('#registrationform').serialize()会自动携带_token参数,无需额外处理。方式2:AJAX请求中设置CSRF头
若表单未加@csrf,在AJAX配置中添加headers:$.ajax({ url: "/save", method: "post", headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, data: $('#registrationform').serialize(), dataType: 'json', success: function(data) { if (data.success) { $("#patientid").val(data.patients.patientid); } else { alert('CNIC already Exists !'); } }, // 添加错误回调,方便调试服务器异常 error: function(xhr) { console.log(xhr.responseText); } })
其他优化建议
- 前端表单验证可简化,直接依赖后端验证规则,后端返回错误后统一展示,避免重复编写逻辑。
- 测试
IdGenerator生成的ID是否唯一,若出现重复,可检查包的配置或改用Laravel自带的自增ID。 - 控制器中可使用
$request->only()批量获取字段,简化赋值代码:$patientData = $request->only(['fname', 'lname', 'cnic', ...]); $patientData['patientid'] = $patientid; Patient::create($patientData);
内容的提问来源于stack exchange,提问作者user19704437
相关产品推荐
相关产品推荐

