CodeIgniter ODBC连MS SQL时Query Builder报错及原生SQL问题求助
问题分析与解决方案
我来帮你逐个拆解这两个登录功能的问题:
1. Query Builder 报错:Call to undefined method CI_DB_odbc_driver::select()
原因
CodeIgniter的ODBC驱动在早期版本(比如CI 2.x)中并没有实现Query Builder(原Active Record)的相关方法,像select()、from()、where()这些链式调用的方法都不存在于CI_DB_odbc_driver类里,直接调用自然会触发“方法未定义”的错误。即便升级到CI 3.x+,ODBC驱动对Query Builder的支持也远不如官方专为SQL Server开发的sqlsrv驱动完善。
解决方案
- 方案一:改用原生查询(配合安全写法):这是最直接的适配方式,后面会详细讲正确的原生查询写法;
- 方案二:切换到SQL Server专用驱动:如果你的服务器环境支持,换成
sqlsrv驱动(需要提前安装PHP的sqlsrv扩展),它完全支持Query Builder,你原来的Model代码就能直接正常运行。只需修改application/config/database.php的驱动配置:$db['default']['dbdriver'] = 'sqlsrv';
2. 原生SQL报错:Invalid column name 'F'
原因
你拼接SQL语句时犯了两个关键错误:
- 密码变量
$password没有加引号,当输入的密码是F这类字符时,SQL会把它当成数据库列名而非字符串值,因此报错“无效列名”; - 直接将用户输入拼接进SQL语句,存在极高的SQL注入风险,恶意用户可以构造特殊输入篡改查询逻辑,甚至窃取整个数据库的数据。
解决方案
使用CodeIgniter提供的**参数绑定(预处理语句)**功能,它会自动处理字符串的引号问题,同时彻底规避SQL注入风险。修改你的原生查询代码如下:
public function login($username, $password) { // 使用问号占位符进行参数绑定 $query = $this->db->query( 'SELECT * FROM utilizadores WHERE username = ? AND password = ?', array($username, $password) ); // 检查并返回查询结果 if ($query->num_rows() > 0) { return $query->result_array(); } else { return false; } }
或者用更清晰的命名绑定写法:
public function login($username, $password) { $query = $this->db->query( 'SELECT * FROM utilizadores WHERE username = :username AND password = :password', array( 'username' => $username, 'password' => $password ) ); return $query->num_rows() > 0 ? $query->result_array() : false; }
额外安全建议:密码存储规范
最后必须提醒你,绝对不要明文存储用户密码!当前直接将密码存入数据库的做法存在极大安全隐患。正确的流程是:
- 用户注册时,用
password_hash()对密码进行哈希存储:$hashed_password = password_hash($user_input_password, PASSWORD_DEFAULT); // 将$hashed_password存入数据库的password字段 - 用户登录时,用
password_verify()验证密码:// 先根据用户名查询数据库中的哈希密码 $query = $this->db->query('SELECT * FROM utilizadores WHERE username = ?', array($username)); if ($query->num_rows() > 0) { $user_data = $query->row_array(); // 验证输入密码与哈希值是否匹配 if (password_verify($password, $user_data['password'])) { // 密码验证通过,返回用户信息 return $user_data; } } return false;
内容的提问来源于stack exchange,提问作者Marco Silva
相关产品推荐
相关产品推荐

