我开始在我的代码点火器模型中进行验证/消毒,在深入研究之前,我正在寻找一些关于最佳实践的建议。控制器的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"等。