使用Codeigniter与模型进行交互的最安全方式

时间:2016-06-03 14:23:57

标签: codeigniter security model

我只是想知道在使用代码点火器时查询数据库最安全的方法是什么。 目前我的模型查询看起来像:

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;
    }

}

但这是最安全的方式吗?如果没有,有没有人知道更安全的方式? 提前谢谢。

2 个答案:

答案 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很好,因为它认为以下所有内容都是空的:FALSE0,空数组,空字符串(“”),{{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; }