CodeIgniter4 PUT请求返回200但数据库字段被置为Null问题排查
问题:CodeIgniter4 PUT更新数据时字段被置为Null
基于CodeIgniter4搭建供Android Studio+Retrofit调用的CRUD API,执行PUT请求更新数据时,PostMan返回200 OK且日志显示成功,但MySQL数据库中本该被替换的字段被置为Null。已尝试修改MySQL表的Null属性,无效;POST请求功能正常。
Controller代码
<?php namespace App\Controllers; use CodeIgniter\RESTful\ResourceController; use App\Models\Modelmahasiswa; class Mahasiswa extends ResourceController { // Start - readData public function index() { $modelMhs = new Modelmahasiswa(); $data = $modelMhs ->findAll(); $response = [ 'status' => 200, 'error' => "false", 'message' => 'Yeay!, Data Loaded Successfully', 'totaldata' => count($data), 'data' => $data, ]; return $this ->respond($response, 200); } // End - readData // Start - searchData public function show($cari = null) { $modelMhs = new Modelmahasiswa(); $data = $modelMhs->orLike('mhsnobp', $cari) ->orLike('mhsnama', $cari)->get()->getResult(); if (count($data)>1) { $response = [ 'status' => 200, 'error' => "false", 'message' => 'Yeay!, Data Available >1', 'totaldata' => count($data), 'data' => $data, ]; return $this ->respond($response, 200); } else if (count($data) == 1) { $response = [ 'status' => 200, 'error' => "false", 'message' => 'Yeay!, Data Available == 1', 'totaldata' => count($data), 'data' => $data, ]; return $this ->respond($response, 200); } else { return $this->failNotFound('Ups!, '.$cari.' Not Found'); } } // End - readData public function new() { // } // Start - createData public function create() { $modelMhs = new Modelmahasiswa(); $nobp = $this->request->getPost('mhsnobp'); $nama = $this->request->getPost('mhsnama'); $alamat = $this->request->getPost('mhsalamat'); $prodi = $this->request->getPost('prodinama'); $tgllahir = $this->request->getPost('mhstgllhr'); $validation = \Config\Services::validation(); $valid = $this->validate([ 'mhsnobp' => [ 'rules' => 'is_unique[mahasiswa.mhsnobp]', 'label' => 'NOID', 'errors' => [ 'is_unique' => 'Ups!, {field} Already Added' ] ] ]); if (!$valid) { $errors = $validation->getErrors(); $response = [ 'status' => 404, 'error' => true, 'message' => $errors['mhsnobp'] ]; return $this->respond($response,404); } else { $modelMhs ->insert([ 'mhsnobp' => $nobp, 'mhsnama' => $nama, 'mhsalamat' => $alamat, 'prodinama' => $prodi, 'mhstgllhr' => $tgllahir, ]) ; $response = [ 'status' => 201, 'error' => "false", 'message' => 'Yeay!, Data Saved Successfully', ]; return $this->respond($response, 201); } } // End - createData // Start - updateData public function update($nobp = null) { $model = new Modelmahasiswa(); $data = [ 'mhsnama' => $this->request->getVar("mhsnama"), 'mhsalamat' => $this->request->getVar("mhsalamat"), 'prodinama' => $this->request->getVar("prodinama"), 'mhstgllhr' => $this->request->getVar("mhstgllhr"), ]; $model->update($nobp, $data); $response = [ 'status' => 200, 'error' => null, 'message' => "Yeay!, Data $nobp Updated Successfully", ]; return $this->respond($response); } // End - updateData // Start - deleteData public function delete($nobp = null) { $modelMhs = new Modelmahasiswa(); $cekData = $modelMhs->find($nobp); if($cekData) { $modelMhs->delete($nobp); $response = [ 'status' => 200, 'error' => null, 'message' => "Yeay!, Data Deleted Successfully", ]; return $this->respondDeleted($response); }else { return $this->failNotFound('Not Found'); } } // End - deleteData }
Model代码
<?php namespace App\Models; use CodeIgniter\Model; class Modelmahasiswa extends Model { protected $table = 'mahasiswa'; protected $primaryKey = 'mhsnobp'; protected $allowedFields = ['mhsnobp', 'mhsnama', 'mhsalamat', 'prodinama', 'mhstgllhr']; }
相关截图
- MySQL表配置截图
- 更新前MySQL表数据截图
- 更新前PostMan Get请求响应截图
- PostMan PUT请求响应截图
- 更新后PostMan Get请求响应截图
- 更新后MySQL表数据截图
- 修改表Null属性后的截图
- 修改后PostMan响应截图
问题排查与解决方案
核心原因
PUT请求中,代码未正确获取到前端传递的参数,导致$data数组中的字段值为null,最终更新到数据库时将字段置空。而POST请求使用getPost()能正常获取参数,是因为getPost()仅处理POST方法的表单数据,PUT请求需确保参数获取方式正确。
解决步骤
验证PostMan请求格式
- 确保PUT请求的参数传递方式正确:选择
x-www-form-urlencoded或form-data,字段名与代码中的mhsnama、mhsalamat等完全一致。 - 检查请求头的
Content-Type是否为application/x-www-form-urlencoded(表单格式)或application/json(JSON格式)。
- 确保PUT请求的参数传递方式正确:选择
调试参数获取情况
在update方法中添加调试代码,确认是否获取到参数:public function update($nobp = null) { var_dump($this->request->getVar()); // 打印所有获取到的参数 die; // 原有代码... }如果输出为空,说明参数未正确传递或未被解析。
修改参数获取逻辑
- 若使用JSON格式传递参数,改用
getJSON()解析:$input = $this->request->getJSON(true); // true转为关联数组 $data = [ 'mhsnama' => $input['mhsnama'] ?? null, 'mhsalamat' => $input['mhsalamat'] ?? null, 'prodinama' => $input['prodinama'] ?? null, 'mhstgllhr' => $input['mhstgllhr'] ?? null, ]; - 若使用表单格式,可尝试使用
getRawInput()手动解析:parse_str($this->request->getRawInput(), $input); $data = [ 'mhsnama' => $input['mhsnama'] ?? null, 'mhsalamat' => $input['mhsalamat'] ?? null, 'prodinama' => $input['prodinama'] ?? null, 'mhstgllhr' => $input['mhstgllhr'] ?? null, ];
- 若使用JSON格式传递参数,改用
仅更新有值的字段
避免将null值写入数据库,过滤掉空参数:$data = []; if ($this->request->getVar('mhsnama')) { $data['mhsnama'] = $this->request->getVar('mhsnama'); } if ($this->request->getVar('mhsalamat')) { $data['mhsalamat'] = $this->request->getVar('mhsalamat'); } if ($this->request->getVar('prodinama')) { $data['prodinama'] = $this->request->getVar('prodinama'); } if ($this->request->getVar('mhstgllhr')) { $data['mhstgllhr'] = $this->request->getVar('mhstgllhr'); } // 只有当$data不为空时执行更新 if (!empty($data)) { $model->update($nobp, $data); }检查模型配置
确认模型的allowedFields包含所有需要更新的字段,当前配置['mhsnobp', 'mhsnama', 'mhsalamat', 'prodinama', 'mhstgllhr']是正确的。
内容的提问来源于stack exchange,提问作者BUdiAKmal
相关产品推荐
相关产品推荐

