Правила     Закладки     Карма    Календарь    Журналы    Помощь    Поиск    PDA    Чат   
        СМС-ки
   
Пейджер выключен!
 
Фильтр авторов:    показать 
  скрыть
  Ответ в темуСоздание новой темыСоздание опроса

> Грамотно ли организована структура MVC, самописный MVC-движок
NewEXE  
 ۩  [x] Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Новичок
*

Профиль
Группа: Пользователь
Сообщений: 1
Пользователь №: 43408
На форуме: 2 месяца, 10 дней
Карма:




Доброго времени суток! Делаю свой движок с нуля (проект маленький, да и самому интересно).
Обычный MVC: роутер, запросы направляются на главный файл /index.php, там $router->run(), в котором вызывается контроллер и экшн (например, в site.ru/site/index управление передается в SiteController, actionIndex с параметрами GET, POST и FILES, если переданы).

Есть два варианта проектирования моделей и контроллеров, как мне кажется, оба приемлемы. Покажу на мини примере регистрации юзера.

Вариант 1. Создать приватные поля в модели, контроллер создаёт и использует объект модели для изменения состояния и передачи его на вид


/* Модель */
<?php
class
User
{
const PIN_LENGTH = 4;

private $id_user;
private $email;
private $password;
private $pin;
private $power;
private $pseudo_balance;
private $role;

function __construct()
{
//сложный конструктор, изменяющий состояние объекта в зависимости от кол-ва параметров, с которыми вызван (иначе сказано: несколько конструкторов преобразования)
}


public function register() //метод публичный нестатический, изменяет состояние объекта (присваивается id_user, вставленный в базу)
{
$hashedPassword = password_hash($this->password, PASSWORD_DEFAULT);
$sql = 'INSERT INTO User (email, password, pin)'
.' VALUES (:email, :password, :pin)';

$result = $GLOBALS['DBH']->prepare($sql);
$result->bindParam(':email', $this->email, PDO::PARAM_STR);
$result->bindParam(':password', $hashedPassword, PDO::PARAM_STR);
$result->bindParam(':pin', $this->pin, PDO::PARAM_STR);
if($result->execute())
{
$this->id_user = $GLOBALS['DBH']->lastInsertId();
return $this;
}
return false;
}

//ещё методы, проверка email, password и т.п.
}

/* Контроллер */

class UserController
{
public function actionSignup($params) //params - обезвреженый массив с данными GET, POST, FILES
{
$email = false;
$password = false;
$pin = false;

$submit = false;
extract($params['post'], EXTR_IF_EXISTS);

$result = false;
if(!empty($submit))
{
$user = new User($email, $password, $pin);
$errors = array($user->checkEmail(), $user->checkPassword(), $user->checkPin()); //методы возвращают текст ошибок или пустую строку
$errors = array_filter($errors);

if(empty($errors))
{

$user->setUserData($email, $password, $pin)
$result = $user->register();
if($result === false)
{
$errors[] = 'Что-то пошло не так при записи в базу данных. Сообщите администратору';
}
}
}


// Подключаем вид
require_once(ROOT.'/views/user/signup.php');
return true;
}


Вариант 2. Модель содержит только статические методы, не содержит полей вообще, контроллер не создаёт объект и обращается через :: к методам модели



/* Модель */

class User
{
const PIN_LENGTH = 4;

//конструктора вообще нет, т.к. объект модели не создаётся

public static function register($email, $password, $pin) //метод публичный статический, никак не изменяет состояние объекта
{
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
$sql = 'INSERT INTO User (email, password, pin)'
.' VALUES (:email, :password, :pin)';

$result = $GLOBALS['DBH']->prepare($sql);
$result->bindParam(':email', $email, PDO::PARAM_STR);
$result->bindParam(':password', $hashedPassword, PDO::PARAM_STR);
$result->bindParam(':pin', $pin, PDO::PARAM_STR);
if($result->execute())
{
$id_user = $GLOBALS['DBH']->lastInsertId();
return $id_user; //в случае успеха вернуть вставленный в базу id
}
return false;
}

//ещё методы, проверка email, password и т.п.

}

/* Контроллер */

class UserController
{

public function actionSignup($params) //params - обезвреженый массив с данными GET, POST, FILES
{
$email = false;
$password = false;
$pin = false;

$submit = false;
extract($params['post'], EXTR_IF_EXISTS);

$result = false;
if(!empty($submit))
{
$errors[] = User::checkEmail($email);
//...и т.д: checkPassword, CheckPin.

if(empty($errors))
{

$result = User::register($email, $password, $pin);
if($result === false)
{
$errors[] = 'Что-то пошло не так при записи в базу данных. Сообщите администратору';
}
}
}


// Подключаем вид
require_once(ROOT.'/views/user/signup.php');
return true;
}




Вопрос: в какой ситуации что лучше сделать? И почему? Любая критика приветствуется, я хочу научиться хорошо программировать. Заранее спасибо

Это сообщение отредактировал NewEXE - 23.09.2016 - 01:36
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
twin  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Глухой нуб
******

Профиль
Группа: Администратор
Почтальон группы
Сообщений: 15559
Пользователь №: 6543
На форуме: 8 лет, 1 месяц, 29 дней
Карма: 299

Трезвый :
5 лет, 11 месяцев, 9 дней


Если тебе это нравится - значит грамотно. Никого не слушай. Сколько людей, столько и мнений. И каждый думает, что именно он программирует грамотно.

По мелочам можно дать пару советов.

1. Не стоит рубить концы. private лучше заменить на protected
2. Вот это:
Цитата
$result->bindParam(':email', $this->email, PDO::PARAM_STR);

можно прописать один раз в настройках коннекта, тогда не нужно будет совать в каждый вызов.
3. Это:
        $email = false;
$password = false;
$pin = false;

$submit = false;
можно сделать компактнее и нагляднее:
        $email = $password = $pin = $submit = false;

4. Если юзаешь extract(), то хотя бы комментами пометь, чего там ожидается. А лучше не юзать.

А остальное придет с опытом. У каждого он свой. Мне вот подготавливаемые выражения в одиночных запрсах кажутся дикостью, а многие считают это серебряной пулей. Или наоборот. Я спокойно отношусь к $GLOBALS['DBH'], а это наверняка раскритикуется. Смотри по стронам и выбирай то, с чем тебе работать комфортно.

Нет и быть не может критерия, по которому можно оценивать качество кода. Ну на определенном уровне я имею ввиду.



--------------------
Если вам недостаточно собственных заблуждений, можно расширить их мнениями экспертов.

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Зачем ворошить старое, когда можно наворотить новое?

user posted image
PMСайт пользователяICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
chee  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Сын полка
Сообщений: 1780
Пользователь №: 38654
На форуме: 2 года, 10 месяцев, 29 дней
Карма: 40




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


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

Мой блог
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
  Быстрый ответ
Информация о Госте
Введите Ваше имя
Кнопки кодов
Для вставки цитаты, выделите нужный текст и
НАЖМИТЕ СЮДА
Введите сообщение
Смайлики
:huh:  :o  ;) 
:P  :D  :lol: 
B)  :rolleyes:  <_< 
:)  :angry:  :( 
:unsure:  :blink:  :ph34r: 
     
Показать всё

Опции сообщения  Включить смайлики?
 Включить подпись?
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:

Опции темы Ответ в темуСоздание новой темыСоздание опроса