CodeIgniter查询中等号被截断?编码Pin查询异常求助
兄弟,你的Pin被截断的问题根源很明确——URI字符过滤规则把Pin里的斜杠/给干掉了!
看你的示例Pin最后是/f4=,但你在config.php里的$config['permitted_uri_chars']只允许了a-z 0-9~%.:_=+-,完全没包含斜杠/。CodeIgniter的URI安全机制会自动移除所有不在允许列表里的字符,所以当你用$this->uri->segment(3)获取Pin时,从第一个/开始的后半段直接被截断了,这就是你看到查询里Pin不完整的原因。
另外,你的模型代码里还有个明显的逻辑bug:子查询select PinID from customer_pins where PinID = '$pin'完全不对啊!$pin是Pin字段的字符串值,不是PinID(主键ID),这会导致子查询永远查不到结果,等于这个“是否已使用”的判断完全失效了。
修复步骤来啦:
1. 先补全URI允许的字符
打开application/config/config.php,把斜杠/加到permitted_uri_chars里:
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_=+-/';
这样URI里的斜杠就不会被过滤,完整的Pin就能被正确获取到。
2. 修正模型的子查询逻辑
原逻辑完全搞错了关联关系,应该先找到Pin对应的PinID,再检查这个ID有没有在customer_pins里被使用。我给你两种写法:
写法一:拆分查询(更直观)
public function check_register_pin($pin){ // 先确认这个Pin本身存在于pins表 $pin_info = $this->db->select('PinID')->where('Pin', $pin)->get('pins'); if ($pin_info->num_rows() === 0) { return false; // Pin都不存在,直接返回无效 } $pin_id = $pin_info->row()->PinID; // 再检查这个PinID未被关联到customer_pins $query = $this->db ->where([ "p.IsDemoPin" => '1', "p.Denomination" => 20, "p.Pin" => $pin ]) ->where("p.PinID NOT IN (SELECT PinID FROM customer_pins WHERE PinID = {$pin_id})") ->get("pins as p"); return $query->num_rows() > 0; }
写法二:联表查询(更高效)
用左连接替代子查询,性能更好,逻辑也更清晰:
public function check_register_pin($pin){ $query = $this->db ->select('p.*') ->from('pins as p') ->join('customer_pins as cp', 'p.PinID = cp.PinID', 'LEFT') ->where([ "p.IsDemoPin" => '1', "p.Denomination" => 20, "p.Pin" => $pin ]) ->where('cp.PinID IS NULL') // 左连接后没有匹配记录,说明未被使用 ->get(); return $query->num_rows() > 0; }
3. 额外优化建议:URL编码传递Pin
因为Pin里包含大量特殊字符,建议在生成跳转链接时先对Pin做URL编码,接收时再解码,避免后续可能的字符解析问题:
- 生成跳转链接时:
$encoded_pin = urlencode($original_pin); redirect(site_url("your_controller/c/{$encoded_pin}"));
- 控制器接收时:
$registerPin = urldecode($this->uri->segment(3));
这样能最大程度保证Pin的完整性,即使以后URI规则变动也不容易出问题。
内容的提问来源于stack exchange,提问作者SBB

