Подтвердить что ты не робот

Разница между контроллером и моделью в 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

Должны ли они быть помещены в контроллер или в модель?

В настоящее время я помещаю все вышеперечисленные функции в контроллер. Правильно ли это?

4b9b3361

Ответ 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 - особенно с помощью форм и хелпера и т.д.