我对MVC框架中的控制器和模型(codeIgniter)感到困惑。我清楚地知道控制器方法调用视图和模型方法与数据库交互。 但是,我对以下类型的方法感到困惑,这些方法由控制器中的方法调用。
hash_password //returns hash password.
valid_email //validates email format and return true or false
is_logged //check if session has a variable, returns true or false
generate_random_string //generates and hashes a random string
它们应该放在控制器还是模型中?
目前,我将所有上述功能都放在控制器中。这是对的吗?
答案 0 :(得分:9)
我认为is_logged
应放在User
的模型中。请注意,User
可能是您的案例中的客户,也可能是您为服务用户建模的任何类。
valid_email
和generate_random_string
或多或少是实用程序函数,您可以将它们放在Utility
或Utilities
模型中,以便它们可以在各种控制器中重复使用你的申请。
hash_password
可以放在User
模型或Utility
模型中。我更倾向于将它放在Utility
模型中,因为它具有散列函数,用户无需关心。但是,我可以想象,否则会有争论。
以下SO问题(虽然对于不同的框架)也可以作为经验法则:
答案 1 :(得分:2)
通常使用控制器来确定如何处理所做的http请求。
创建一些直接响应http请求的函数没有错。
但如果它与数据库有关,最好将这些功能放在模型中,并从控制器中调用它们。
答案 2 :(得分:2)
控制器应该将视图与模型结合起来,因此每个验证都应该放在模型中 这是我来自kohana的例子
CONTROLLER
<?php
/**
* User Controller
*/
class Controller_Admin_User extends Controller_Admin_Template {
public function action_index()
{
$this->template->body = View::factory('admin/user/index')
->set('i', 0)
->bind('users', $users)
->bind('groups', $groups)
->bind('id_user_group', $id_user_group);
$model_user = new Model_Admin_User;
$users = $model_user->get_users(Arr::get($_GET, 'sort'), Arr::get($_GET, 'order'));
$model_usergroup = new Model_Admin_Usergroup;
$groups = $model_usergroup->get_user_group();
}
public function action_add()
{
$this->template->body = View::factory('admin/user/form_add')
->bind('error', $error)
->bind('groups', $groups)
->bind('post', $post);
$model_usergroup = new Model_Admin_Usergroup;
$groups = $model_usergroup->get_user_group();
if($_POST)
{
$model_user = new Model_Admin_User;
if($model_user->save($_POST) == false)
{
$error = $model_user->error;
$post = $_POST;
}
else
{
$this->request->redirect('admin/user');
}
}
}
MODEL
class Model_Back_User extends Model {
private $qb;
public $aliases = array(
'id'=> 'id_user'
);
public $error = array(
'name' => null,
'surname' => null,
'login' => null,
'password' => null,
'id_user_group' => null,
'old_password' => null,
'new_password' => null,
'confirm' => null,
'email' => null,
'phone' => null,
);
private $rules = array(
'name' => array('not_empty' => null, 'alpha' => null),
'surname' => array('not_empty' => null, 'alpha' => null),
'login' => array('not_empty' => null),
'password' => array('not_empty' => null),
'id_user_group' => array('not_empty' => null),
'email' => array('not_empty' => null, 'email' => null),
'phone' => array('not_empty' => null),
'old_password' => array('not_empty' => null),
'new_password' => array('not_empty' => null),
'confirm' => array('matches' => array('new_password'))
);
public function __construct()
{
$this->qb = new Querybuilder;
//parent::__construct();
}
public function change_password($data)
{
$validate = Validate::factory($data)
->filter(true, 'trim')
->rules('old_password', $this->rules['old_password'])
->rules('new_password', $this->rules['new_password'])
->rules('confirm', $this->rules['confirm'])
->callback('old_password', array($this, 'password_exists'), array('id_user'=> $data['id_user']));
if($validate->check() == false)
{
$this->error = array_merge($this->error, $validate->errors('user'));
return false;
}
$u = Session::instance()->get('user');
$this->edit(array('password'=> $this->password($data['new_password'])), array('id_user'=> $u['id_user']));
return true;
}
public function password_exists(Validate $valid, $field, $param)
{
if($this->user_exists(array('password'=> $this->password($valid[$field]), 'id_user'=> $param['id_user'])) == false)
{
$valid->error($field, 'old password is incorrect', array($valid[$field]));
}
}
public function save($data)
{
$validate = Validate::factory($data)
->filter(true, 'trim')
->rules('name', $this->rules['name'])
->rules('surname', $this->rules['surname'])
->rules('user_group_id', $this->rules['id_user_group'])
->rules('email', $this->rules['email'])
->rules('phone', $this->rules['phone']);
$edit = false;
if(isset($data['id_user']) AND Validate::not_empty($data['id_user']))
{
$edit = true;
}
else
{
$validate->rules('login', $this->rules['login'])
->rules('password', $this->rules['password']);
}
if($validate->check() == false)
{
$this->error = array_merge($this->error, $validate->errors('user'));
return false;
}
if($edit == true)
{
$this->edit(
array(
'name' => $data['name'],
'user_group_id' => $data['user_group_id']
),
array(
'id_user'=> $data['id_user']
)
);
return true;
}
return $this->add(
array(
'name' => $data['name'],
'login' => $data['login'],
'password' => $data['password'],
'user_group_id' => $data['user_group_id']
)
);
}
protected function add($data)
{
$data['password'] = $this->password($data['password']);
return $this->_db->query(Database::INSERT,
$this->qb->insert('user')->set($data)->build_query()
);
}
查看并不是那么重要,这就是为什么我不把它放在这里。
答案 3 :(得分:0)
一般来说 - 模型应该知道它自己的数据。因此,任何与模型自身数据完全相关的事情都应该放在模型中。
例如hash_password和email-validation方法 - 模型应该知道如何验证或更新它自己的数据字段,因此这些应该放在模型中。
但是,控制器应该知道如何正确地指导用户操作并为视图等加载正确的模型。
EG与会话相关的方法应该进入控制器,因为会话用于存储用户的状态(基于过去的操作)。
“生成随机字符串”方法非常模糊,可以在任何地方使用。我把它放在可能包含在模型/控制器中的单独库中。
答案 4 :(得分:0)
我已经使用Codeigniter很长一段时间了,我会对你的功能进行以下操作:
hash_password //returns hash password.
我会在库或帮助文件中添加类似密码哈希的内容,以便我可以从我的控制器中调用它:
// pretend library I'd make for tasks like hashing etc
$this->load->library('passwords');
// transform posted password into it's hashed version
$password = $this->password_library->hash_password($this->input->post('password'));
我假设你想要密码/加密密码并将其存储在你的数据库中
valid_email //validates email format and return true or false
这已经在form_validation中了,所以......
is_logged //check if session has a variable, returns true or false
这也应该连接到身份验证库
generate_random_string //generates and hashes a random string
同样,这将来自图书馆或助手。
您何时使用模型?
我,我专门用于数据库的输入/输出模型。我所有的疑问都在那里。我通常让我的模型函数返回数据对象,所以我可以在我的视图中循环它们。
控制器从模型中调用您的数据,然后将所有内容转储到您的视图中。外部功能总是进入库和帮助程序。我喜欢做“MY_library”并扩展Codeigniter自己的东西 - 尤其是表格和html助手等。