以下是我的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
吗?
答案 0 :(得分:2)
codeigniter数据库适配器具有内置的查询参数化;它就像用问号替换每个参数一样简单,并将所有变量作为第二个参数传递给数组。
$this->db->query("SELECT user_id FROM subscriptions WHERE thread_id = ?", array($thread_id));
当你以这种方式设置时,不可能有sql注入,你不必担心转义数据(至少不是SQL部分; XSS和html转义仍然是一个问题)
答案 1 :(得分:1)
Sam的方式是正确的Codeigniter方式。更多标准PHP方式:
$thread_id = intval($thread_id);
$this->db->query("SELECT user_id FROM subscriptions WHERE thread_id = ". $thread_id);
答案 2 :(得分:0)
虽然您必须使用Sam Dufel的答案中的查询,但只是为了回答您的众多问题和假设
我应该在哪里以及如何逃避$ thread_id?
一般规则是 - 尽可能靠近查询大楼 因此,最佳方法是使用占位符,因为它可以保证在插入查询之前正确格式化数据。
由于数据库字段thread_id是一个整数,$ thread_id不应该被查询中的单引号包围。
这不是真的。 只有在严格模式下运行mysql时,才能使用引号 但一般来说,你可以一直使用报价。因此,将数字格式化为字符串是非常可能的解决方案。
所以我想知道如何逃避数字......
唯一转义数字的方法是强制转换它。 intval()
没问题
...在Codeigniter?
如果它允许你使用占位符 - 去吧。
我自己应该检查$ thread_id是否是一个数字,或者有没有办法用Codeigniter来做?
在通常情况下,无需检查。在数据库级别,只需要正确的格式化。
我是否还应该使用escape_like_str()来表示数字?
它会使绝对,绝对没有意义 您是否应该使用流感疫苗来保护您的钱免遭抢劫?和这里一样。这是不同的事情。
我应该在模型或控制器中“验证”$ thread_id吗?
首先,您必须区分输入验证和特定于数据库的格式。
第二个是强制性和无条件的,而第一个是可选的
只要此“验证”与数据库格式无关,您就可以在任何地方执行此操作。
就我个人而言,我会在控制器中执行此操作,并在失败时抛出404。因为它是控制器来执行HTTP特定的操作,而模型必须是与环境无关的 但同样,这种验证与特定于数据库的格式无关,必须始终应用这些格式。
答案 3 :(得分:-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
或ctype_digit
或is_int()
来读取PHP手动或发现自己需要使用的东西。