Где проверить и обработать отправку формы на веб-сайте MVC - PullRequest
2 голосов
/ 28 июня 2011

Я работаю над структурированным веб-сайтом Model-View-Controller на основе PHP.Я понимаю, что Модели должны иметь дело с бизнес-логикой, представлениями представления HTML (или чего-либо еще) пользователю, и контроллеры облегчают это.Где я бегу, застрял с формами. Сколько обработки я помещаю в контроллер и сколько я помещаю в мою модель?

Предположим, что я пытаюсь обновить имя и фамилию пользователя.Я хочу отправить форму с использованием AJAX одному из моих контроллеров.Я хочу, чтобы данные были проверены (снова) на стороне сервера, и, если они действительны, сохраните их в базе данных, а затем верните ответ JSON обратно в представление как успешное или ошибочное.

Должен ли я создатьэкземпляр моей пользовательской модели в контроллере, или я просто должен иметь реле контроллера для статического метода в моей модели?Вот два примера того, как это может работать:

Вариант № 1: Процесс POST в модели

<form action="/user/edit-user-form-submit/" method="post">
    <input type="text" name="firstname">
    <input type="text" name="lastname">
    <button type="submit">Save</button>
</form>

<?php
    class user
    {
        public function __construct($id){} // load user from database
        public function set_firstname(){} // validate and set first name
        public function set_lastname(){} // validate and set last name
        public function save_to_database(){} // save object fields to database

        public static function save_data_from_post()
        {
            // Load the user
            $user = new user($_POST['id']);

            // Was the record found in the db?
            if($user->exists)
            {
                // Try to set these fields
                if(
                    $user->set_firstname($_POST['firstname'])
                    and
                    $user->set_lastname($_POST['lastname'])
                )
                {
                    // No errors, save to the dabase
                    $user->save_to_database();

                    // Return success to view
                    echo json_encode(array('success' => true));
                }
                else
                {
                    // Error, data not valid!
                    echo json_encode(array('success' => false));
                }
            }
            else
            {
                // Error, user not found!
                echo json_encode(array('success' => false));
            }
        }   
    }

    class user_controller extends controller
    {
        public function edit_user_form()
        {
            $view = new view('edit_user_form.php');
        }
        public function edit_user_form_submit()
        {
            user::save_data_from_post();
        }
    }
?>

Вариант № 1: Процесс POST в модели

<form action="/user/edit-user-form-submit/" method="post">
    <input type="text" name="firstname">
    <input type="text" name="lastname">
    <button type="submit">Save</button>
</form>

<?php
    class user
    {
        public function __construct($id){} // load user from database
        public function set_firstname(){} // validate and set first name
        public function set_lastname(){} // validate and set last name
        public function save_to_database(){} // save object fields to database
    }

    class user_controller extends controller
    {
        public function edit_user_form()
        {
            $view = new view('edit_user_form.php');
        }
        public function edit_user_form_submit()
        {
            // Load the user
            $user = new user($_POST['id']);

            // Was the record found in the db?
            if($user->exists)
            {
                // Try to set these fields
                if(
                    $user->set_firstname($_POST['firstname'])
                    and
                    $user->set_lastname($_POST['lastname'])
                )
                {
                    // No errors, save to the dabase
                    $user->save_to_database();

                    // Return success to view
                    echo json_encode(array('success' => true));
                }
                else
                {
                    // Error, data not valid!
                    echo json_encode(array('success' => false));
                }
            }
            else
            {
                // Error, user not found!
                echo json_encode(array('success' => false));
            }
        }
    }
?>

Два примера делают одно и то же, я это понимаю.Но есть ли правильный и неправильный способ сделать это?Я много читал о тощих контроллерах и толстых моделях, откуда появился вариант № 1.Как вы справляетесь с этим?Спасибо и извините за длинный вопрос!

Ответы [ 3 ]

4 голосов
/ 28 июня 2011

Короче говоря, вы можете использовать любой из этих подходов - , но вы должны их немного изменить.

Подумайте об этом: модели на самом деле не «знают» о публикации, получении и еще много чего. Они должны знать только о том, чем они связаны с бизнесом - в вашем случае это пользователь.

Таким образом, хотя можно использовать подход № 1, вы должны не получать доступ к переменным записей непосредственно из модели. Вместо этого заставьте функцию принимать массив параметров, которые затем используются для создания пользователя.

Таким образом, вы можете легко повторно использовать код, например, в сценарии оболочки или где-либо еще, где нет такой вещи, как $_POST.

Хотя второй подход более подробен в контроллере, вы тоже можете это сделать. Однако, возможно, немного лучший подход в стиле заключается в использовании «класса обслуживания». Служба будет иметь метод, скажем, «createUserFromArray», который принимает массив и возвращает пользователя. Опять же, вы должны передать этот метод $_POST в качестве параметров - подобно тому, как вы должны передать их в функцию в измененном # 1.

Только контроллер должен иметь дело со входами напрямую. Это потому, что контроллер обрабатывает запрос, и, следовательно, он может знать о сообщении.

tl; dr ваши модели никогда не должны использовать суперглобальные значения, такие как $_POST напрямую.

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

Основная причина шаблона проектирования MVC заключается в том, что это хороший способ поддержания разделения проблем. Представление должно быть неосведомлено о Модели, и наоборот. Контроллер существует только как некий гаишник, посредник между Моделью и Представлением. Таким образом, Контроллер должен взять данные из Представления, выполнить минимальную обработку, необходимую для того, чтобы Модель могла понимать данные без необходимости знать, как реализовано Представление (то есть через форму HTML), и передать их Модели, чтобы модель может сохранить данные.

Это позволяет использовать модель в других случаях, когда необходимо создать / сохранить / сохранить элемент другими способами, кроме HTML-формы, без дублирования кода сохранения элемента на нескольких контроллерах.

ОБНОВЛЕНИЕ: я забыл упомянуть проверку. В том же ключе, что и для сохранения данных, Контроллер должен взять данные и передать их в Модель для проверки, так как Модель - это та, которая знает точный формат данных, которые ему нужны. Вы можете объединить валидацию и постоянство, если Модель сгенерирует исключение, если данные недопустимы, которые Контроллер может перехватить и обработать при необходимости (например, отобразить ответ об ошибке JSON.)

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

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

В вышеприведенных комментариях говорилось, что модели не нужно знать о $ _POST или $ _GET, это пользовательский ввод, с которым должен работать контроллер.С другой стороны, модель должна обрабатывать все данные, передаваемые ей, поскольку вы определенно не хотите снова и снова проверять данные в другой части кода вашего проекта.

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