Разница между контроллером и моделью в MVC
Я немного запутался в отношении контроллера и модели в среде MVC (codeIgniter). Мне ясно, что методы контроллера называют представления и методы Model взаимодействуют с базой данных.
Тем не менее, я немного запутался в следующих типах методов, которые вызываются методами в контроллере.
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
Должны ли они быть помещены в контроллер или в модель?
В настоящее время я помещаю все вышеперечисленные функции в контроллер. Правильно ли это?
Ответы
Ответ 1
Я думаю, что is_logged
следует поместить в Model для User
. Обратите внимание, что User
может быть клиентом в вашем случае или любым классом, который вы создали, чтобы смоделировать пользователя вашей службы.
valid_email
и generate_random_string
являются более или менее полезными функциями, которые можно разместить в модели Utility
или Utilities
, чтобы они были повторно использованы в разных контроллерах вашего приложения.
hash_password
может быть помещен либо в модель User
, либо в модель Utility
. Я больше склоняюсь к тому, чтобы поместить его в модель Utility
, поскольку его функция хэширования и пользователь ничего не заботится. Однако я могу представить, что в противном случае могут быть аргументы.
Следующий вопрос SO (хотя и для другой структуры) также может служить эмпирическим правилом:
Где разместить пользовательские функции в Zend Framework 1.10
Ответ 2
Обычно контроллеры используются для определения того, как обрабатывать сделанные http-запросы.
Нет ничего плохого в создании некоторых функций, которые непосредственно отвечают на HTTP-запросы.
но если это имеет какое-либо отношение к БД, лучше разместить эту функцию в модели и вызвать их из контроллера.
Ответ 3
Контроллер должен комбинировать представление с моделью, поэтому каждая проверка должна быть помещена в модель
это мой пример из kohana
КОНТРОЛЛЕР
<?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');
}
}
}
МОДЕЛЬ
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()
);
}
Просмотр не так важен, поэтому я не помещаю это здесь.
Ответ 4
Вообще говоря, модель должна знать материал о своих собственных данных. Так что все, что связано с моделью собственных данных, должно идти в модели.
Например, методы hash_password и проверки электронной почты - модель должна знать, как проверять или обновлять собственные поля данных, поэтому они должны идти в модели.
Однако контроллер должен знать, как правильно управлять действиями пользователя и загружать правильные модели для просмотров и т.д.
EG, связанный с сеансом метод должен идти в контроллере, потому что сеанс используется для хранения пользовательского состояния (на основе прошлых действий).
Метод "генерировать случайные строки" очень расплывчатый и может использоваться повсеместно. Я бы поместил это в отдельную библиотеку, возможно, включив ее в модель/контроллер.
Ответ 5
Я использую 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 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
Опять же, это будет происходить из библиотеки или помощника.
SO Когда вы используете модель?
Me, я использую модели исключительно для ввода/вывода в базе данных. Все мои вопросы идут туда. Обычно у меня мои функции модели возвращают объекты данных, поэтому я могу прокручивать их в своих представлениях.
Контроллеры вызывают ваши данные с ваших моделей, а затем сбрасывают все в ваши представления. Внешняя функциональность всегда идет в библиотеки и помощники. Мне нравится делать "MY_library" и расширять собственные материалы Codeigniter - особенно с помощью форм и хелпера и т.д.