@edvardpotter

Правильно ли я понимаю MVC?

Знакомый попросил написать небольшую систему для управления лицензиями(сам он пишет на си). Я решил писать с использованием MVC. Вопрос такой - правильно ли я понял этот паттерн, вот пример авторизации на сайте:
Controller_Login.php
<?php

class Controller_Login extends Controller
{
	function __construct()
	{
		Session::init();
		$logged = Session::get('login');
		if($logged == false) {	
		$this->model = new Model_Login();
		$this->view = new View();
		}
		else header('Location: ../main');			
	}
	
	function action_index()
	{
		if(!empty($_POST['login'])&& !empty($_POST['password'])){
				$data = $this->model->login($_POST['login'],$_POST['password']);	
		}		
		$this->view->generate('login.php',array('data' => $data,'title'=> "Авторизация"));
	}
	
	function action_logout()
	{			
		$this->model->logout();
	}
	
}


Model_Login.php
<?php

class Model_Login extends Model
{
	public function login($login, $password)
    {
		$link = self::db();	
		$login    = $link->real_escape_string(htmlspecialchars($login));
		$password = $link->real_escape_string(htmlspecialchars(md5(md5($password))));
		$query    = "SELECT user_id, email, user_group,name FROM dle_users WHERE name= '$login' AND password = '$password' LIMIT 1";
		$sql = $link->query($query);
		if (mysqli_num_rows($sql) == 1) {
			$row = $sql->fetch_assoc();
			if ($row['user_group'] == 7 || $row['user_group'] == 1) {						
				Session::set('id',$row['user_id']);  
				Session::set('email',$row['name']);  
				Session::set('group',$row['user_group']);  
				Session::set('login',$row['email']);  	
				header("Location: ../main");
			} else{
				$data['msg']= "Ваша группа не соответствует требованиям!";							
			}
		} 
		else {			
			$data['msg']= "Неверное имя пользователя или пароль. Проверьте правильность введенных данных!";					
		}
		$link->close();
		return $data;
	}	
}


Надо ли было создавать глобальные переменные в модели, и делать сеттеры и геттеры?
  • Вопрос задан
  • 916 просмотров
Решения вопроса 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
нет, вы не правильно поняли MVC.

Попробуйте подойти к проблеме чуть с другой стороны. Реализуйте ваше приложение так, что бы оно ничегошеньки не знало о HTTP, внутри него небыло ни единого echo, оно ничего не знало о сессиях и вообще ничего не знал о таких вещах. Проще всего этого добиться - ваше приложение можно запускать через CLI. Грубо говоря как-то так:

<?php
// run.php - просто скрипт для разового теста

require __DIR__ . '/vendor/autoload.php'; // вы же уже используете composer?

$app = new App();
$app->getService('login_handler')->login('user@example.com', 'password');


Что-то типа такого. То есть на каждый "юз кейс", то есть то что приложение должно делать, у вас должен быть метод. Типа "сделай то-то" и "сделай еще что-то".

Вот это - наше приложение, наша "модель". Не один какой-то класс... это все приложение. MVC же ставит перед собой задачу снижения связанности между UI и приложением. Цель при этом приследуется простая - UI обычно меняется намного чаще чем логика приложения, а стало быть лучше их друг от дружки отделить целиком и полностью.

Делается это за счет того что между UI и приложением вводят дополнительный промежуточный слой адаптеров - контроллеры (это опять же не обязательно один объект, это может быть целая цепочка адаптеров, каждый из которых делает что-то конкретное, в плодь до последнего адаптера который уже конвертирует http запрос в нужный вызов нужного метода).

То есть что бы сказать "я сделал MVC" у вас приложение не должно зависить от UI. Если вы хоть где-то в приложении используете суперглобальные массивы, и т.д. вы проиграли. Ну либо просто не называйте это MVC, скажите что вы просто шаблоны отдельно ложите ну и роутер еще есть. Но это не MVC, это smartui, то есть наше приложение вкурсе что у него есть UI и они сильно связаны.

MVC нужно далеко не всем, и smartui сойдет для простых проектов. Но вы должны понимать разницу, и знать когда стоит загоняться а когда можно логику в контроллеры выносить.

Надо ли было создавать глобальные переменные в модели

Это вы еще не уяснили значит что такое ООП, почему глобальное состояние плохо и что такое побочные эффекты (погуглите в контексте состояния).

делать сеттеры и геттеры?

А этим мы нарушаем инкапсуляцию. Внешний мир должен знать только что можно делать с моделью, но никак не ее структуру. То есть вместо setSomething у вас должно быть осмысленное название, типа updateSomething, changeSomething и т.д. Типа "user should be able to change password" и у вас появляется метод "changePassword". Или "User should be able to update profile details" и у вас появляется один единственный метод "updateProfileDetails()". А что оно как состояние меняет - это консерн исключительно объекта. Ему рашеть менять чего или нет. Мы таким образом изолируем побочные эффекты и уменьшаем вероятность багов. Ну и нам не нужно валидировать при таком раскладе ничего так как нет промежуточного невалидного состояния.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
jacksparrow
@jacksparrow
Кратко: если проект пишите для реальной задачи - возьмите фреймворк
Ответ написан
trevoga_su
@trevoga_su
htmlspecialchars
ответь сам себе на вопрос - каким боком функция замены символов, являющихся частью html, у тебя присутствует при работе с БД? Это бред.

Вообще, что бы написать в MVC стиле, нужно иметь базу ООП знаний и, в целом, надо иметь то ли фрейморк, то ли просто код твой должен быть разделен на слои... без этого писать на MVC по большей части затея бессмысленная.

Сейчас у тебя типичный код, обернутый в классы.

Ну и на www.phpinfo.su/articles/theory/model_view_controll...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы