我只是想知道在使用代码点火器时查询数据库最安全的方法是什么。 目前我的模型查询看起来像:
function getDetails($filename){
$this->db->select('*');
$this->db->from("mydatabase");
$this->db->where("filename",$filename);
$query = $this->db->get();
if($query->num_rows()>0){
return $query->result();
}
else{
return $query->result();
}
}
或者:
function getUsername($username){
$this->db->where('username', $username);
$query = $this->db->get('users');
foreach ($query->result() as $row)
{
return $row->username;
}
}
但这是最安全的方式吗?如果没有,有没有人知道更安全的方式? 提前谢谢。
答案 0 :(得分:3)
取决于“安全”和“安全”的含义。假设“安全”意味着检查变量是否有效(意味着定义和设置),那么getDetails()
是安全的,而getUsername()
则不是那么多。
使用行if($query->num_rows()>0){
确保第一个安全,您断言查询返回了一些行。一个建议,请考虑这个结构。
if($query->num_rows()>0){
return $query->result();
}
else
{
return NULL;
//return $query->result(); would return an empty array which might be OK
//if you account for that possibility in the calling function.
//But if that's the case why the `if` statement?
//Skip the conditional and just return $query->result()
}
或者,使用三元运算符可以更优雅地编写if
条件,而不是return $query->num_rows()>0 ? $query->result() : NULL;
条件。
$result = $this->model_name->getDetails($filename);
if(empty(result))
{
//handle the lack of data
}
else
{
//do stuff with $result
}
当查询没有产生结果时,我喜欢从模型中返回NULL。在调用函数中检查返回值,如此
empty()
PHP函数NULL
很好,因为它认为以下所有内容都是空的:FALSE
,0
,空数组,空字符串(“”),{{1 (0作为整数),0.0
(0作为浮点数),“0”(0作为字符串)。然后涵盖了大多数基地。
getUsername($username)
安全性较低,因为查询可能没有返回任何行。这可能会导致函数的未设置var,从而为此分配返回值。没有任何行,foreach
将无法运行,getUsername($username)
将返回无效。如果您对isset()
调用指定的var使用getUsername($username)
,则不一定会出现问题。
就“安全”而言,你处于良好状态,因为使用where()
例如$this->db->where('username', $username);
将自动转义输入值。用户输入始终是主要关注点和可能的攻击。
答案 1 :(得分:1)
Dfriend有一些很棒的观点。我只是要坚持下去,因为这是一个非常有价值的基本模式。
您写道:
if($query->num_rows()>0){
return $query->result();
}
else{
return $query->result(); // editors note: no no no
}
我不会像Dfriend一样礼貌 - 不要这样做。令人困惑的是看起来并不准确。这是一种方式:
if($query->num_rows()>0){
return $query;
}
else{
return FALSE;
}
一个考虑因素是,如果要返回多行的结果 - 那么只返回模型中的$ query。然后,您可以选择以后的方法和视图。
在控制器中,您始终要检查您是否从数据库中找到了任何内容。即使您有记录,并且您的php服务器正在运行,数据库连接也可能会崩溃。 Dfriends的方式非常好,这有点不同。基本上我们首先检查非条件。如果没有找到结果,那么我们将针对该条件采用一种方法。这使您的方法集中,易于理解。
// if the query result was false, then show a different view
if( ! $query = $this->model->getDetails($searchTerm)
{
$this->showNoResultsFor($searchTerm);
}
// if you return just $query you have all these options available
// in your controller and/or view
else
{
// get one row
$query->row() ;
// get number of records returned
$query->num_rows();
// the records as object
$query->result() ;
// pass query to your view
$data['query'] = $query ;
// pass the number of found results to view
$data['found'] = $query->num_rows();
// pass just the records to view
$data['results'] = $query->result() ;
}
例如,显示视图文件中返回的记录数 - 非常常见。或者需要从一组记录中抓取一条记录。这就是为什么我建议返回$ query。终于到现在你已经意识到这很尴尬
foreach ($query->result() as $row)
{
return $row->username; // editors note: no no and no
}
如果您正在搜索您知道必须像表记录ID一样唯一的东西 - 并且只能有一个结果 - 那么检查一个结果并返回该行。
if($query->num_rows() == 1){
return $query->row();
}
else{ return false; }