我应该如何处理代码点火器模型中的错误


How should i handle errors in my Codeigniter Models?

我开始在我的代码点火器模型中进行验证/消毒,在深入研究之前,我正在寻找一些关于最佳实践的建议。控制器的form validation库很好,但显然我不想依赖控制器来向我发送好的数据。

目前,我返回布尔值,成功时返回TRUE(或数据),失败时返回FALSE,这使得很难将错误消息传递回调用者。我想摆脱失败时的错误。

虽然我绝对不是一个专家,但我已经开始阅读了很多关于Exceptions的文章,并在外部库中遇到了很多,它们似乎是一个很好的候选者。我的问题是,这种例外情况的使用是否恰当?模型误差是例外误差吗?

一个可能的例子:

<?php
class person_model extends CI_Model{
    public function getPersonById($personId){
        //check for int
        if(!is_int($personId) OR $personId < 0){
            throw new Exception('Invalid person ID');
        }
        //setup query
        $this->db->select('*')
            ->where('personId', $personId);
        //run query
        $result = $this->db->get('person');
        //failed to get
        if(!$result){
            throw new Exception('DB query failed');
            //should i also return false?
            return FALSE;
        }
        //got info
        else{
            return $result;
        }
    }
}
?>

谢谢你的帮助!

编辑:

我不得不说,我对那些建议数据验证只能在控制器中进行的回复感到非常惊讶。模型是数据存储的最后一道屏障。模型是数据和应用于该数据的规则,即应用程序逻辑。对我来说,数据验证似乎是应用程序逻辑。此外,您可能有许多控制器访问相同的模型方法。您想依靠两个控制器实现相同的验证吗?这在我看来很傻。

此外,并非所有数据都来自用户输入,其中一些数据可以由编写控制器的程序员硬编码到脚本中。当你的模型需要一个整数时,如果他们传递了一个字符串,该怎么办?或者传递一个格式错误的日期?模特不应该说些什么吗。

我对讨论持开放态度,但我觉得数据验证肯定属于模型。(除了控制器,甚至视图(为了方便起见,html5/javascript))

我发现的处理此问题的最简单方法是始终首先使用if检查来检查否定条件。这也使得检查多个步骤变得容易。

只要可能,总是从模型方法返回一些东西。甚至在这个例子中——我们需要验证表单——我会使用codeigners表单验证来验证它是一个整数等。如果它通过了验证,那么我们需要$personId来进行数据库搜索。因此,不只是从验证中返回true/false-如果验证通过,则返回$personId:

function getperson() {
 // Validate the form 
 // AND if its valid, return the validated $personId 
 // Note the separate private method if the validation failed 
 if ( ! $personId = $this->person->_validateGetPersonForm() ) {
     $this->error_msg = 'Error in validating the form. Please use a number.';
 $this->_showGetPersonFailed() ; }
 elseif ( ! $person = $this->person->getBy($personId)  ) {
$this->error_msg = 'There is no person in our records with the number:'. $personId;
$this->_showGetPersonFailed() ; }
 else {  $this->_showResultsFor($person) ; } 
  } 

$this->error_msg可自动用于您的任何视图,并且由于我们已经中断了验证和数据库搜索,因此错误消息很容易适用于确切的条件。如果搜索失败,则有一个私有方法_showGetPersonFailed()可以再次显示表单。最后一个if/else通常是成功的&有一个单独的私有方法来处理用适当的视图显示结果。

还建议不要像"person_model"那样在文件名中使用单词"model"。它只是打乱了整个命名,并迫使你一遍又一遍地键入单词model:-)这样想:如果你从控制器调用某个东西并得到结果,它几乎总是一个模型。并且所有模型文件将始终位于名为models的文件夹中。

转到:

application/config/database.php

并搜索db_debug为TRUE。例如:

...
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE; //<-- Have this to true
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
...

在我的模型中,我从不抛出异常或错误。对于返回null的查询,我总是返回false。如果您的代码中存在SQL错误,代码点火器会自动通知您。如果您的查询没有返回结果,我将避免抛出异常。然后,如果查询返回false,则可以使用控制器处理该查询。

编辑:您还应该检查被查询到控制器数据库中的数据,而不是模型。在我看来,该模型应该严格用于查询数据,而不是用于错误/数据检查,您可以在提交控制器之前这样做。

一个例子:

型号

function search_replies($term){
    $this->db->like('ticket_id', $term);
    $this->db->or_like('reply_from', $term);
    $this->db->or_like('reply_from_name', $term);
    $this->db->or_like('reply_content', $term);
    $query = $this->db->get($this->table_ticket_replies);
    // Returns the result if the number of rows is greater than 0, returns false otherwise        
    if ($query->num_rows() > 0) return $query->result();
    return false;
}

控制器

function example_controller(){
    if($this->search_model->search_replies('Test')){
        $data['results'] = $this->search_model->search_replies('Test');
    }
    $this->load->view('search_results', $data);
}

查看

<?php 
if(isset($results)){
    echo 'Retrieved Results';
    foreach($results as $result){
    }
} else{
    ?>
    <h2>No results for search term!</h2>
    <?php
}
?>

您可能错过了用户指南中表单验证页面的这一部分:

单独显示错误

用法:

echo form_error('field_name');

只需输入您正在使用的任何字段名称来代替"field_name",例如"username"或"email"等。