Разница между контроллером и моделью в MVC - PullRequest
12 голосов
/ 21 июня 2011

Я немного запутался в контроллере и модели в среде 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

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

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

Ответы [ 5 ]

9 голосов
/ 21 июня 2011

Я думаю, что is_logged следует поместить в модель для User.Обратите внимание, что User может быть клиентом в вашем случае или любым классом, который вы сделали для моделирования пользователя вашей услуги.

valid_email и generate_random_string - это более или менее вспомогательные функции, которыеВы можете поместить их в модель Utility или Utilities, чтобы их можно было повторно использовать в различных контроллерах вашего приложения.

hash_password можно разместить либо в модели User, либо в Utility модель.У меня больше соблазна поместить его в модель Utility, так как это функция хеширования, и пользователь ничего не заботит.Однако я могу представить, что в противном случае могут быть аргументы (аргументы).

Следующий вопрос SO (хотя и для другой структуры) также может служить практическим правилом:

Гдепоставить пользовательские функции в Zend Framework 1.10

2 голосов
/ 21 июня 2011

Контроллер должен объединять вид с моделью, поэтому каждый валидатор должен быть размещен в модели это мой пример из кохана

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()
        );
    }

Вид не так важен, поэтому я не ставлю это здесь.

2 голосов
/ 21 июня 2011

Обычно контроллеры используются для определения того, как обрабатывать запросы http.

Нет ничего плохого в создании некоторых функций, которые напрямую отвечают на запросы http.

но если это имеет какое-либо отношение к БД, лучше поместить эти функции в модель и вызывать их из контроллера.

0 голосов
/ 22 июня 2011

Я давно использую 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

Это уже в проверке формы, так что ...

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 и т. Д.

0 голосов
/ 21 июня 2011

Вообще говоря, модель должна знать что-то о своих данных. Поэтому все, что связано исключительно с собственными данными модели, должно входить в модель.

Например, методы hash_password и email-validation - модель должна знать, как проверять или обновлять свои собственные поля данных, поэтому они должны входить в модель.

Однако контроллер должен знать о том, как правильно направлять действия пользователя и загружать правильные модели для представлений и т. Д.

Например, метод, связанный с сеансом, должен идти в контроллере, поскольку сеанс используется для хранения состояния пользователя (на основе прошлых действий).

Метод «генерировать случайную строку» очень расплывчатый и может использоваться везде. Я бы поместил это в отдельную библиотеку, возможно, включенную в модель / контроллер в зависимости от ситуации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...