我该如何处理Codeigniter模型中的错误?

时间:2013-12-10 20:42:01

标签: php codeigniter model

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

目前我返回bool值,成功时返回TRUE(或数据),失败时返回FALSE,这使得将错误消息传递回调用者非常困难。我想在失败时摆脱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))

4 个答案:

答案 0 :(得分:1)

我发现处理此问题的最简单方法是始终首先使用if check 检查否定条件。这也可以轻松检查多个步骤。

始终尽可能从模型方法返回一些东西。就像在这个例子中一样 - 我们需要验证表单 - 我会使用codeigniters表单验证来验证它是一个整数等,如果它通过验证然后我们需要$ 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-&gt; error_msg可自动用于您的任何视图,因为我们已经完成了验证和数据库搜索 - 错误消息很容易适用于确切的条件。如果搜索失败,则有一个私有方法_showGetPersonFailed()再次显示该表单。最后一个if / else通常是成功的 - 有一个单独的私有方法来处理用适当的视图显示结果。

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

答案 1 :(得分:0)

转到:

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'] = '';
...

答案 2 :(得分:0)

在我的模型中,我从不抛出异常或错误。我总是在返回null的查询上返回false。如果您的代码中存在SQL错误,则codeigniter会自动通知您。如果你的查询没有返回任何结果,我会远离抛出异常。 然后,如果查询返回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
}
?>

答案 3 :(得分:0)

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

Showing Errors Individually

用法:

echo form_error('field_name');

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