0

这是我的 Codeigniter 应用程序中模型内的函数示例。

function is_subscriber($thread_id) {
    $this->db->query("SELECT user_id FROM subscriptions WHERE thread_id = $thread_id");
}

我应该在哪里以及如何逃脱$thread_id?由于数据库字段 thread_id 是整数$thread_id,因此在查询中不应用单引号括起来。所以我想知道我应该如何在 Codeigniter 中转义数字?我应该自己检查是否$thread_id是数字,还是有办法用 Codeigniter 来做?

我发现escape_like_str()哪个转义而不添加引号,而不是添加引号的 escape()。我也应该使用escape_like_str()数字吗?

$thread_id其次,我应该在模型中还是在控制器中“验证” ?

4

4 回答 4

2

codeigniter 数据库适配器具有内置的查询参数化;它就像用问号替换每个参数一样简单,然后将数组中的所有变量作为第二个参数传递。

$this->db->query("SELECT user_id FROM subscriptions WHERE thread_id = ?", array($thread_id));

当您以这种方式进行设置时,就没有 sql 注入的可能性,并且您不必担心转义数据(至少对于 SQL 部分而言不是;XSS 和 html 转义仍然是一个问题)

于 2013-03-13T22:36:46.863 回答
1

Sam 的方式是执行此操作的正确 Codeigniter 方式。如需更多标准 PHP 方式:

$thread_id = intval($thread_id);
$this->db->query("SELECT user_id FROM subscriptions WHERE thread_id = ". $thread_id);
于 2013-03-13T22:42:10.813 回答
0

尽管您必须使用 Sam Dufel 的答案中的查询,但只是为了回答您的众多问题和假设

我应该在哪里以及如何转义 $thread_id?

一般规则是 - 尽可能靠近查询构建。
因此,最好的方法是使用占位符,因为它可以保证数据在插入查询之前正确格式化。

由于数据库字段 thread_id 是一个整数 $thread_id 不应在查询中用单引号引起来。

这并不完全正确。只有在严格模式下运行 mysql 时,才不能使用引号。
但总的来说,您可以一直使用引号。因此,将数字格式化为字符串是很可能的解决方案。

所以我想知道我应该如何逃避数字......

逃避数字的唯一方法是强制转换它。intval()没关系

... 在 Codeigniter 中?

如果它允许您使用占位符 - 去吧。

我应该自己检查 $thread_id 是否是一个数字,还是有办法用 Codeigniter 做到这一点?

一般来说,不需要检查。在数据库级别,只需要正确的格式

我还应该对数字使用 escape_like_str() 吗?

绝对,绝对没有意义。
你应该使用流感疫苗来保护你的钱不被抢劫吗?这里也是。是不同的事情。

我应该在模型或控制器中“验证” $thread_id 吗?

首先,您必须区分输入验证和特定于数据库的格式
第二个是强制性的和无条件的,而第一个是可选的。
只要这种“验证”与 DB 格式化无关,您可以在任何地方进行。

就个人而言,我会在控制器中执行此操作,并在失败时抛出 404。因为它是执行 HTTP 特定操作的控制器,而模型必须与环境无关。
但同样,这样的验证与必须始终应用的特定于数据库的格式无关。

于 2013-03-14T05:09:57.223 回答
-1

使用标准查询时,您可能希望$this->db->escape_like_str()像这样使用

$sql = 'SELECT name FROM users WHERE id = '.$this->db->escape_like_str($id).'AND user_id ='.$this->db->escape_like_str($user_id).'LIMIT 1';

或者:

$sql = 'SELECT name FROM users WHERE id = ? AND user_id = ? LIMIT 1'
$query = $this->db->query(array($id,$user_id));

这种方法不验证数字只是为了安全而将它们转义,如果你想验证一个数字,你可以使用 PHP 原生函数,或者is_numeric你可以阅读 PHP 手册或发现你自己需要使用什么。.ctype_digitis_int()

于 2013-03-13T23:58:00.130 回答