如何在 CodeIgniter 中使用准备好的语句
Posted
技术标签:
【中文标题】如何在 CodeIgniter 中使用准备好的语句【英文标题】:How can I Use Prepared Statements in CodeIgniter 【发布时间】:2012-12-18 20:22:35 【问题描述】:大家好,我需要在我的站点中使用准备好的语句。我试过用这个
$sql = "SELECT * FROM tbl_user WHERE uid=:id and activation_key=:key";
$query = $this->db->query(
$sql,
array( ':id' => $uid ,':key' => $activation_key)
);
但这不起作用。当我将 :id
和 :key
更改为 ?
时,它的工作原理。
【问题讨论】:
【参考方案1】:CodeIgniter 不支持预处理语句。如果您查看 CI 的 Database 类的源代码,您会发现它们只需将问号替换为传递的数组中的数据即可解决绑定:
https://github.com/EllisLab/CodeIgniter/blob/develop/system/database/DB_driver.php#L874它们仅支持带有未命名占位符的查询绑定。见http://ellislab.com/codeigniter/user-guide/database/queries.html
查询绑定
绑定使您能够通过让系统为您将查询放在一起来简化查询语法。考虑以下示例:
$sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?"; $this->db->query($sql, array(3, 'live', 'Rick'));
查询中的问号自动替换为查询函数第二个参数中数组中的值。
和http://ellislab.com/forums/viewthread/105112/#528915
尽管 CI 不支持预处理语句,但它支持查询绑定。使用准备好的语句,您必须调用某种类型的 prepare() 函数,然后调用某种类型的 execute() 函数。使用查询绑定,您只需调用一个函数,它基本上做同样的事情。正因为如此,我更喜欢查询绑定而不是准备好的语句。
在旁注中,将?
更改为:foo
只是从未命名绑定更改为命名绑定(CI 显然也不支持)。仅仅因为您使用或不意味着您正在准备语句。
【讨论】:
【参考方案2】:我遇到了这个问题,因为我遇到了类似的问题。答案是正确的,CI 不支持准备好的语句。但是,并不意味着您不能使用准备好的语句!
在以下示例中,我使用 PDO 作为连接类,但以下代码将起作用:
$q = $this->db->conn_id->prepare('SELECT * FROM tbl_user WHERE uid=? and activation_key=?');
$q->execute(array($param1,$param2));
print_r($q->fetchAll());
注意 conn_id 是您可以针对其运行准备好的语句的 PDO 对象。
然而,这将不允许您获取本机 CI 函数允许的查询字符串。为此,您将需要 Get Last Executed Query in PHP PDO 之类的东西。
此外,这不会阻止您使用查询构建器来构建您的语句,然后您可以在 PDO 准备中使用这些语句。例如 -
$db->where('uid = ?',null,false);
$db->where('activation_key = ?',null,false);
$q = $this->db->conn_id->prepare($db->get_compiled_select('tbl_user'));
如果您输出$db->get_compiled_select('tbl_user');
,将构建查询并允许您查看基本查询
【讨论】:
CI + 安全准备语句 这个答案就是炸弹。任何使用 CI 的人都应该考虑鼓励这些人在他们的代码中公开正确准备好的语句。 模拟 PDO 是个谎言! 在 CI4(并且不是任何早期版本)中,它们有一个 altogether new class structure that uses PDO with actual parameter binding。 +1 以获得最佳答案。以上是关于如何在 CodeIgniter 中使用准备好的语句的主要内容,如果未能解决你的问题,请参考以下文章