CodeIgniter 4 问题:数据无法插入pemesanan表求助
问题描述
我遇到了数据无法插入pemesanan表的问题。已通过dd($data)确认数据为数组格式,但调用$PemesananModel->save($data)后,数据并未插入到数据库中,恳请协助解决。
控制器
数据从produk1()方法传递至视图,再由视图提交至add_pesan方法:
public function produk1() { $model = new ProdukModel(); $pemesananModel = new PemesananModel(); $data['getProduk'] = $model->getData(); $data['cart'] = \Config\Services::cart(); $noAntrian = $pemesananModel->generateNoAntrian(); $idKaryawan = 1; $idPemesan = "P" . date('md') . rand(3, 1); $data['id_pemesan'] = $idPemesan; $data['id_pelanggan'] = session()->get('id_pelanggan'); $data['id_karyawan'] = $idKaryawan; $data['no_antrian'] = $noAntrian; $data['tgl'] = date('Y-m-d'); $data['status_pembayaran'] = "cash"; $data['status_pemesanan'] = 'Dalam Antrian'; $data['nama_pelanggan'] = session()->get('nama_pelanggan'); $data['no_hp'] = session()->get('no_hp'); echo view('user/produk', $data); } public function add_pesan() { $pemesananModel = new PemesananModel(); $id_pemesan = $this->request->getPost('id_pemesan'); $id_pelanggan = (int)session()->get('id_pelanggan'); $id_karyawan = 1; $noAntrian = (int)$pemesananModel->generateNoAntrian(); $tgl = $this->request->getPost('tgl'); $status_pembayaran = $this->request->getPost('status_pembayaran'); $status_pemesanan = $this->request->getPost('status_pemesanan'); $data = [ 'id_pemesan' => $id_pemesan, 'id_pelanggan' => $id_pelanggan, 'id_karyawan' => $id_karyawan, 'no_antrian' => $noAntrian, 'tgl' => $tgl, 'status_pembayaran' => $status_pembayaran, 'status_pemesanan' => $status_pemesanan ]; log_message('info', 'Data to be saved: ' . print_r($data, true)); if ($pemesananModel->save($data)) { session()->setFlashdata('pesan', 'Berhasil Pesan'); } else { $errors = $pemesananModel->errors(); log_message('error', 'Failed to save data: ' . print_r($errors, true)); session()->setFlashdata('error', 'Gagal Pesan: ' . implode(', ', $errors)); } return redirect()->to('/produk1'); }
视图
接收produk1传递的数据并提交至add_pesan:
<form action="/add_pemesanan" method="post"> <input type="hidden" name="id_pemesan" value="<?= $id_pemesan ?>" class="hidden"> <input type="hidden" name="id_pelanggan" value="<?= $id_pelanggan ?>" class="hidden"> <input type="hidden" name="id_karyawan" value="<?= $id_karyawan ?>" class="hidden"> <input type="hidden" name="no_antrian" value="<?= $no_antrian ?>" class="hidden"> <input type="hidden" name="tgl" value="<?= $tgl ?>" class="hidden"> <input type="hidden" name="status_pembayaran" value="<?= $status_pembayaran ?>" class="hidden"> <input type="hidden" name="status_pemesanan" value="<?= $status_pemesanan ?>" class="hidden"> <button type="submit" id="cartIcon" class="flex items-center p-4 bg-indigo-500 text-white font-semibold rounded hover:bg-indigo-600"> <i class="fas fa-shopping-cart"><?= $all_item; ?></i> </button> </form>
模型
<?php namespace App\Models; use CodeIgniter\Model; class PemesananModel extends Model { protected $table = 'pemesanan'; protected $primaryKey = 'id_pemesan'; protected $allowedFields = [ 'id_pemesan', 'id_pelanggan', 'id_karyawan', 'no_antrian', 'tgl', 'status_pembayaran', 'status_pemesanan' ]; public function generateNoAntrian() { $lastOrder = $this->orderBy('id_pemesan', 'DESC')->first(); if ($lastOrder) { $lastNoAntrian = (int)substr($lastOrder['no_antrian'], 2); $newNoAntrian = $lastNoAntrian + 1; } else { $newNoAntrian = 1; } return str_pad($newNoAntrian, 4, '0', STR_PAD_LEFT); } public function getData($id = false) { $builder = $this->db->table($this->table); $builder->select('pemesanan.no_antrian, pelanggan.no_hp AS no_hp, pemesanan.tgl, pemesanan.status_pembayaran, pemesanan.status_pemesanan, pelanggan.nama_pelanggan AS nama_pelanggan, karyawan.nama AS nama_karyawan'); $builder->join('pelanggan', 'pelanggan.id_pelanggan = pemesanan.id_pelanggan'); $builder->join('karyawan', 'karyawan.id_karyawan = pemesanan.id_karyawan'); if ($id !== false) { $builder->where('pemesanan.id_pemesan', $id); } $query = $builder->get(); return $query->getResult(); } public function getData_for_pelanggan($id = false) { if ($id === false) { return $this->findAll(); } else { return $this->getWhere(['id_pemesan' => $id]); } } }
路由
$routes->get('/produk1', 'AdminController::produk1'); $routes->match(['get', 'post'], '/add_pemesanan', 'AdminController::add_pesan');
数据库结构

问题排查与解决方法
no_antrian类型不匹配
数据库中no_antrian是varchar类型,但add_pesan中把生成的带前导零的字符串强制转为int,导致数据格式丢失。去掉强制转换:$noAntrian = $pemesananModel->generateNoAntrian();主键
id_pemesan重复
当前idPemesan生成逻辑"P" . date('md') . rand(3,1)极易重复,优化生成规则:$idPemesan = "P" . date('YmdHis') . rand(1000, 9999);缺少CSRF令牌
CodeIgniter默认启用CSRF保护,表单未提交令牌会被拦截,添加令牌字段:<input type="hidden" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>">id_pelanggan为空验证
未登录时session()->get('id_pelanggan')为null,转int后变为0,若数据库字段不允许空则插入失败,添加登录校验:$id_pelanggan = session()->get('id_pelanggan'); if (!$id_pelanggan) { session()->setFlashdata('error', '请先登录'); return redirect()->to('/login'); } $id_pelanggan = (int)$id_pelanggan;查看错误日志
检查writable/logs目录下的日志文件,根据log_message记录的错误信息定位具体问题,或直接打印$pemesananModel->errors()获取验证失败详情。
内容的提问来源于stack exchange,提问作者AtepRiandi Pahmi
相关产品推荐
相关产品推荐

