Модель-Представление-Контроллер где это в Друпале?
Судя по названию:
/modules/custom/mysumm/src/Controller/FirstPageController.php
- это Контроллер?
А форма это что?:
/modules/custom/mysumm/src/Form/MessagesForm.php
- тоже Контроллер?
А где Модель? Где Представление?
Спасибо.
Комментарии
Тут все сложнее так как сам друпал намного сложнее многих фреймворков
Контроллер - принимает разные запросы и отправляет их в другие части системы а также получает от них ответ.
Другие части системы могут считаться грубо моделью. Они как правило связаны с базой данных и обрабатывают данные с нее своей логикой
Представление это все шаблоны твига..
Не знаю может ли препроцессы и тд относится к представлениям
Что-то вопрос получился из категории "где в этом доме архитектура"?
MVC - это концепция построения веб-приложений (и не только веб). По сути современный Друпал - это и есть паттерн Model-View-Controller.
Если угодно, то эти понятия можно технически представить так:
1. Модель - абстрактная совокупность механизмов обработки данных (например, обращение к БД: запрос данных - реакция/обработка - предоставление результата). То есть, сама логика какой-то конкретной программы/приложения. Для удобства/простоты можно вообразить, что модель находится над двумя остальными компонентами, хотя это необязательно так. Модель может меняться на протяжении взаимодействия с ней пользователя (например, разные формы Друпала с разной логикой). Абстрактной модель считается потому, что она не обязана (и не должна) быть способной напрямую получать данные от пользователя или отдавать их (этим занимается контроллер и представление).
2. Представление - отображение/вывод результатов работы модели и/или интерфейсов взаимодействия с моделью. Грубо говоря, можете считать, что это Views в Друпале (как и прочие сугубо программные способы вывода данных). А также формы, кнопки и пр. компоненты интерфейса.
3. Контроллер - механизм получения данных от пользователя и возвращения результатов обработки. В Друпале контроллеры присутствует везде, где есть обращения по любым URL'ам: страницы, формы, AJAX-процедуры и т.д. Код класса контроллера не обязательно должен находится именно в папке src/Controller (например, формы тоже имеют свои контроллеры).
Не стоит искать прямые параллели MVC в мнемонике или традициях/соглашениях именования компонентов Друпала. Программно/технически код модели и контроллера может находиться как в одном классе/файле, так и на разных абстрактных уровнях. Также и представление может физически быть частью класса/файла контроллера (хоть это и моветон в большинстве случаев).
Модель - это всё, что связано с хранением данных. Это, как уже упоминали, сервисы для обращения к БД. Плюс все имплементации EntityStorage, плюс Drupal::config() и Drupal::state(). Это только первое, что пришло на ум, наверняка есть что-то ещё, но используется значительно реже.
Представление - это, помимо шаблонов и препроцессов, все эти рендер-массивы, сам renderer, плюс всё, что связано с форматтерами и блоками. Ну и, наверное, самое главное - \Drupal\Core\Render\MainContent\HtmlRenderer. Кто не в курсе, именно этот класс отвечает за то, в какой теме рендерить страницу, какие блоки выводить, какие библиотеки подключать.
Ну и контроллер - это контроллер. Только надо помнить, что помимо классов в папке src/Controller, есть ещё куча системных контроллеров, роут-провайдеров и прочего барахла, которое тоже относится именно сюда.
То есть по сути, всё это довольно чётко разделено и практически нигде не смешивается. Единственное, что есть всякие опенкарты, где model-view-controller - это конкретно названия папок, поэтому многие, видя папку Controller, начинают искать model и view)))
Вообще, по большому счёту - Мрак
Обработать форму, сделать запрос и вывести - это 10 строк на PHP. Вот и всё MVC.
А тут - целые простыни.
Вот именно. Ведь главная концепция этой всей возни:
Облегчение поддержки кода.
Отличное сравнение. Заходя в хрущёвку я точно зная что дверь в коридоре ведёт в туалет в котором есть и ванна тоже.
Что вам даст это знание (где в Друпале компоненты MVC) в практическом смысле? Это, как писалось выше, только концепция, паттерн, шаблон.
Применительно к вашему комментарию - достаточно знать, что в квартире/доме всё же есть туалет/ванна. То есть, на пол испражняться не следует, для этого есть специальное помещение. Это всё, что требуется. А реализованы (размещены) они могут быть где угодно. И выяснить это не так сложно.
Хочу всё-таки разобраться до конца. Например:
На странице есть форма, сама на себя. Обработчик. И Таблица:
<?php
// Модель -->>> $mysqli = new mysqli('localhost', ...);
$result = $mysqli->query("SELECT * FROM node_field_data
Where type='".$_GET['type']."'"); // Контроллер -->>>
$u = '<table border="1">';
while (
$r = $result->fetch_object()) {$u .= "<tr><td>$r->nid<td>$r->title
<td>$r->langcode<td>$r->type \n";
}
$u .= '</table>'; ?>
<?php
// Представление -->>>
?>
<form>
<input name="type"> <input type="submit">
</form>
<?=$u?>
Так? Или в Контроллере должны остаться только переменные?
Имхо, вы тут таки пытаетесь смешивать мух с котлетами. Думаю, если всё же попытаться натягивать шаблон MVC на приведённый код, то (как-то очень условно):
1. Цикл while (проход по рядам) - это всё таки ещё модель. Модель на выходе должна дать все результирующие данные, без разметки и форматирования.
2. Контроллер в идеале должен получать запросы и возвращать самые-самые конечные результаты пользователю, но не заниматься форматированием в таблицу, это задача представления. Хотя на практике случается, что контроллер что-то таки форматирует тоже. Собственно, в вашем коде контроллер вообще отсутствует. Точнее - он подразумевается в виде типичного HTTP запроса и ответа веб-сервера. Можно сказать - ваш код уже работает внутри контроллера "по умолчанию". А если бы в вашем примере на вход скрипта поступали какие-то управляющие параметры (например, из вашей же формы) и их следовало предварительно обрабатывать каким-то кодом (например, проверять роль) или далее передавать в модель (скажем, кол-во рядов для запроса), то этот кусочек кода очень условно можно было бы назвать контроллером.
3. Таким образом, представление у вас начинается примерно со строчки
<?php$u = '<table border="1">';?>
и следует до конца кода.PS. Думаю, у вас вообще проблемы с абстрагированием кода. Я сужу в том числе и по другим вашим постам. Иными словами, вы привыкли сваливать PHP-код в одну кучу или в лучшем случае разбивать его по каким-то частным функциональным признакам, лишь бы самому было удобно в нём ориентироваться и "всё было под рукой". Этот подход работает до тех пор, пока вы пишете что-то для себя или для каких-то очень частных задач. Или не нагруженный проект. И, наверное, это тоже подход. Но как только возникнет необходимость передавать код другому Друпал-программисту или привести его к стандартам Друпала с целью лучшей интеграции с возможностями ядра (кеширование, оптимизация запросов и пр), или другими модулями системы - вас ждут многие неприятные сюрпризы.
Тут мораль одна: чем меньше велосипедов в реализации - тем органичнее она вольётся в среду Друпала и окружение проекта. А чтобы не было велосипедов - нужно ЗНАТЬ систему.
А почему бы не сделать всё по drupal-way?
Так сделаем потом. И сравним всё.
Или про что вы? Это чистый PHP.
И где же он чистый, когда там половина кода HTML?
Дописал обработку Гета.
<?php
// Модель -->>>
if(preg_match("/[^a-z]/", $_GET['type'])) $_GET['type']='page'; $mysqli = new mysqli('localhost', ...);
$result = $mysqli->query("SELECT * FROM node_field_data
Where type='".$_GET['type']."'"); // Контроллер -->>>
$u = '<table border="1">';
while (
$r = $result->fetch_object()) {$u .= "<tr><td>$r->nid<td>$r->title
<td>$r->langcode<td>$r->type \n";
}
$u .= '</table>'; ?>
<?php
// Представление -->>>
?>
<form>
<input name="type"> <input type="submit">
</form>
<?=$u?>
Переписал:
<?php // Контроллер -->>>
if(preg_match("/[^a-z]/", $_GET['type'])) $_GET['type']='page'; // Модель -->>> $mysqli = new mysqli('localhost', ...);
$result = $mysqli->query(
"SELECT * FROM node_field_data Where type='".$_GET['type']."'"); $i=0;
while ($r = $result->fetch_object()) {
$u[$i] = [$r->nid,$r->title,$r->langcode, $r->type];
++$i;
} // Представление -->>>
?>
<form>
<input name="type"> <input type="submit">
</form>
<table border="1">
<?php
foreach($u as $v) {
print "<tr><td>$v[0]<td>$v[1]<td>$v[2]<td>$v[3] \n";
}
?>
</table>?>
Что произойдет, если в запросе передать
?type=';UPDATE TABLE users_field_data SET mail='account@evil.site' WHERE uid=1
?Что-то вроде этого, если сильно зажмуриться. )
Однако. Канонический кошерный контроллер хотел бы вернуть ответ "Нет результатов", если их нет (т.е. SQL-запрос вернул ноль рядов). Или "Ошибка в параметрах", если параметр не передали или передали с ошибкой (в вашем случае будет фатальной ошибкой передать, например, не буквенное значение, а числовое, типа ?type=0).
Также канонический контроллер хотел бы знать, где заканчивается его тело с тем, чтобы при выходе из него вернуть
награбленноесобранные отформатированные результаты запроса. Таким образом, функционал "модели" должен быть выведен из общей кучи в отдельную процедуру, которую контроллер мог бы вызвать, если всё ОК с входными параметрами.Аналогично и с представлением. Контроллер бы желал вызвать процедуры представления, передав им результаты, полученные от модели. А потом получить эти результаты в оформленном виде и, наконец, отдать пользователю.
Так что (чисто формально) весь ваш код - только тело контроллера с некоторыми намёками на MVC. Но уже лучше. )
Мрак. Возвращаясь к архитектуре - Если необходимо ответить на все эти вопросы перед тем как сходить на унитаз... - я посикаю на улице.
На самом деле это вопрос привычки. Вы же бессознательно задаётесь вопросом как закрыть дверь в туалете и закрываете её, прежде чем приступить к процессу. Или, скажем, не пытаетесь это делать стоя боком к унитазу, а выбираете одну из двух подходящих позиций. То есть, вы выполняете какой-то определённый привычный алгоритм. Он кажется технически сложнее, чем просто снять (или даже не снять) штаны и пристроиться на газоне (или в любом месте, где вздумается). Но при должном воспитании вам всё же сложнее (и дискомфортнее) будет делать это случайным образом на улице, чем в удобстве, уединении и тиши уборной.
Красивый код пишется для программистов. Бизнесу нужен рабочий код, ему все равно на красоту а тем более есть красота стоит денег...и еще каких..
Поэтому и балансируем между хотелками заказчика и своими даже если они обоснованны и обсусловлены технологическими факторами
Бизнесу надо чтобы этот код ещё и поддерживался и расширялся как можно большее время.
А красота кода это - хорошая архитектура и хорошая читаемость. То есть - это напрямую надо заказчику. Если, конечно, это не какой-нибудь лендинг, который никто и никогда менять не будет.
Я конечно тут мимокрокодил, но по моему программирование это не ваше, автор. На этот код без слез не взглянешь
И что же вас заставляет рыдать?
Вся эта архитектура не с пустого места развивалась. Чтобы понять как и что происходило , стоит почитать книгу про становление компьютеров , какие были победы и поражения, и как исправляли ошибки
Как появилось ООП, высокоуровневые языки и дополнительные абстракции
Вообще тут нет правого пути или левого
Вы можете забить гвоздь в бетон и молотком и зубилом.
А можете использовать перфоратор и дюбель с винтом
Решать вам . В каждом способе есть минусы и плюсы
Вот могут закричать. Перфоратор круче...А вдруг нет электричества? Скажут - аккумулятор..
В ответ скажу а вдруг под дождем и нужно крутить пару месяцев и зарядить нельзя..Так что молоток и зубило наше все
Выдаст список page. Вы правда не понимаете?
Вы правда не понимаете, что у админа поменяется почта?
Есть мысль, что таки в конкретно этом случае будет просто ошибка SQL. Поскольку экранировано одинарными кавычками.
<?php
$result = $mysqli->query(
"SELECT * FROM node_field_data Where type='".$_GET['type']."'");
?>
Т.е. если в запросе передать
?type=';UPDATE TABLE users_field_data SET mail='account@evil.site' WHERE uid=1
, то запрос расширится до первой одинарной кавычки в :<?php
$result = $mysqli->query(
"SELECT * FROM node_field_data Where type=';UPDATE TABLE users_field_data SET mail='");
?>
Оставшаяся часть вызовет ошибку синтаксиса SQL. Могу и ошибаться, конечно.
Хотя в целом это дыра.
Вот так будет выглядеть строка запроса:
"SELECT * FROM node_field_data Where type='';UPDATE TABLE users_field_data SET mail='account@evil.site' WHERE uid=1'"
да, в конце надо добавить
;'
, специально оставил так.Один раз я предложил заказчику после проверки работоспособности - немного подправить код чтоб он был красивей и запросил за это денег. Заказчик очень быстро ответил - что всё и так хорошо.
Чистота кода важна там - где продают именно код.
Дык, а где тут речь о красоте или чистоте кода? О чём это вообще сейчас? Автор топика просит, чтобы ему разжевали концепцию MVC на примере куска его кода. Вот и стараемся, как получается, и говорим сугубо о функциональной стороне и структуре кода. Это без придирок собственно к качеству кода.
Хотя и код у автора - да, мягко говоря, не на высоте.
Нет. Не поменяется.
Почему?
Сказали А. - Говорите Б
А зачем? Мы ж с вами уже объяснились в своё время. Я вам признался, что я цыган и не котирую высшее образование. Я также не читал брошюрки о Друпале за завтраком в ВУЗе, как это делали вы. Что вам с того, что я что-то там критикую или одобряю?
Поэтому:
<?php if(preg_match("/[^a-z]/", $_GET['type'])) $_GET['type']='page'; ?>
Они - правда не понимают. Где я?
И что? Запрос Андрюхи не удовлетворяет условию вашей проверки, следовательно
$_GET['type']
не будет изменён вашим "фильтром" и пойдёт в неизменном виде в SQL-запрос.Пересмотрел ещё раз ваш код - признаю, не обратил внимание на инвертирование маски
"/[^a-z]/"
. Да, ваш фильтр не пропустит Андрюхин запрос.А можете объяснить, чем обращение к $_GET лучше чем current_request? И почему решили отказаться от использования entity_type.manager для загрузки нод?
Ну ок, регуляркой проверяется, чтобы значение параметра type содержало только латинские буквы в нижнем регистре. А завтра появится тип контента spec_page, и код придется править, а затем потребуется передавать в значение фильтра числа или адреса электронной почты, а затем этот проект попадет в шаловливые ручки джуна, который просто выпилит эту проверку, т.к. до регулярок он еще не добрался.
Зачем оставлять в коде такие мины?
\Drupal::database()->select()
чем не устраивает? Гарантированно никаких INSERT и UPDATE там не получится выполнить.\Drupal::request()->query->get()
чем не устраивает? Можно централизованно альтерить параметры запроса (например, отдельным security-модулем), вместо того чтобы каждый раз проверять значения регулярками.Почему бы вообще не сделать эту страницу вьюсом?
Понимаете, вам построили туалет с теплым полом и гигиеническим душем, а вы по привычке на улицу бегаете.
Напишите где нибудь код.
Дело в том что мой код работает на куче сайтов и везде его пробовали ломать.
Я ещё когда его писал подумал - сейчас будет список недопрограммистов.
Мне очень страшно оказаться в вашем списке недопрограммистов. Поэтому ничего писать не буду. Да и вообще - я здесь просто понты кидаю. Умничаю-с.
Там есть один подвох. Но вряд ли вы его знаете.
Извините, но обучение у меня - платное
Там всё-таки есть неточность. В чём она?
Неточности - это примерно о половине вашего кода, если уж зарыться. Ну что, попробуем прикинуть. Навскидку:
1. В случае отсутствия (т.е. непередачи) параметра
?type=...
вы получите PHP notice, причём несколько раз. А такая ситуация может быть.2. Массив
$u
не объявляется (хотя бы в пустом виде) перед телом<?php while ($r = $result->fetch_object()) ?>
. И если SQL-запрос не даст результатов, то этой переменной не будет. Однако ниже вы без проверки пытаетесь её читать в цикле<?php foreach($u as $v) { ?>
. Опять же, получите PHP notice или даже ошибку.2.
preg_match()
возвращает как числовое значение (0 или 1), так и FALSE в случае ошибки. Соответственно, результат может требовать строгой проверки типа (===). В вашем случае это некритично, однако более точная конструкция будет вида:<?php
if(preg_match("/[^a-z]/", $_GET['type']) === 1) $_GET['type']='page';
?>
PS. И зачем я всё это пишу, надо оно мне? )
Честность - это хорошо.
Это ирония
Я говорил именно про это.
Тут получается что если написать Гет с ошибками - то будет плохо
Например, с какими ошибками?
Собственно, из вышеприведённого перечня это наиболее безобидная неточность в вашем случае. Поскольку PHP (слава Богу) в операторах сравнения понимает что и 0 и FALSE - не ИСТИНА. Стало быть, поскольку вы проверяете именно истинность результата preg_match(), то в вашем случае сработает только 1, остальные два возможных результата просто не имеют значения.
Намного хуже всё остальное (п.1 и 2).
Не поможет.
А чем вас пугают уведомления? Мне правда интересно.
Тем, что ваш код вместо любого (хотя бы) результата не даст вообще ничего, кроме ошибок на экране. Недостаточно?
В общем, хватит на сегодня. Видимо, тема исчерпала свой интригующий потенциал. С вами было приятно пообщаться.
Очень даже имеет значение и именно в этом самом случае - когда истина - это плохо А Фальш - это хорошо.
<?php
if($u=preg_match("/[^a-z]/", $_GET['type']) and $u!=false) $_GET['type']='page';
?>
<?php if($u=preg_match("/[^a-z]/", $_GET['type']) or $u===false) $_GET['type']='page'; ?>
Не будет никаких ошибок. Есть функция в PHP которая регулирует - выводятся предупреждения или нет.
В Друпале - тоже это есть.
Вот:
http://chajnik.ru/validacija
я официально разрешаю это ломать. Это мой сайт. Это тестирование.
Ломать можно. И показать. Но не вредить
Вот код:
<?php
print $_GET['type'];if(
$u=preg_match("/[^a-z]/", $_GET['type']) or $u===false) $_GET['type']='page';print
'<p>';print $_GET['type'];
?>
<form>
<input name="type"> <input type="submit">
</form>
?>
Сколько же флуда буквально на пустом месте
И демо приготовили, вообще прелесть
Для ответа на вопрос нужно базовое представление что такое MVC у человека, который это спрашивает.
Дальше мы можем посмотреть на то, как друпал обрабатывает запрос
Не хочу вставлять картинку, она очень большая, да и комментариев к ней в статье очень много.
Как только будет понимание того, что такое MVC и как друпал рендерит страницы - сразу отпадут вопросы, как у топикстартера
Вы правда не видите что это не Друпал?
А написано что друпал))))))
и что же это?
Блин. Эту проверку с регуляркой - хоть не пиши вообще.
Недопрограммисты просто пройти мимо этого не могут.
Я такое писал уже на нескольких сайтах по разным поводам. Везде набегают недопрограммисты и дружно, массово лажаются, но продолжают упорствовать.
Самое смешное когда набегает 2-я или 3-я волна и начинает умничать не дочитав до конца уже 3 раза разжованное
Но но но, давайте без оскорблений участников сообщества
Это не моё. Это цитата. Вы правда - не понимаете?
Очень интересно, что человек создаёт тему о том, что не понимает, где в друпале модель, где вью, а где контроллер. Но при этом понимает, что такое друпал, а что такое не друпал. Что ж. Очень хочется отведать секретных знаний. Имею следующие вопросы:
1. Почему \Drupal::database()->select() - это не друпал.
2. Почему обращение к $_GET лучше, чем Drupal::request()
3. Почему решили отказаться от использования entity_type.manager для загрузки сущностей.
Понимаю, что хочу слишком многого, но готов заплатить. Назови сумму, сколько денег нужно, чтобы ты написал ответы на эти вопросы в этом топике.
Обычный запрос к БД. Вы правда - не понимаете?
И таблица node_field_data в БД тоже не друпальная, просто так совпало.
Ссылки для связи про работу - есть в личке. Вы правда про это не знаете?
Супер-пупер программисты - так хорошо.
Горе-программисты?
Согласитесь - у них должно быть название.
Или предложите вы - как их называть?
Называйте их разработчиками.
Они стараются не использовать регулярки, рекурсивные вызовы, и разную php-магию не потому, что они недопрограммисты, а потому, что отдают себе отчет, что с этим кодом будут работать их коллеги.
И чем проще и понятнее другим будут их решения, тем быстрее и качественнее будет вестись веб-разработка, особенно - в команде.
А за такими надпрограммистами, пишущими код по одним им известным паттернам - приходится потом этот код выносить на помойку, и делать по-человечески.
БД бывает Друпальная или недрупальная?
БД - не важно что в ней храниться. Друпал или Вордпресс. Запросы абсолютно одинаковы.
Препад по Гидраврике говорил, что тех кто не понимает Роторы - нужно расстреливать.
А Роторы посложней будут чем Регулярки
Всем доброго вечера. Видимо, банкет продолжается.
Да бросьте. Скрыть ошибки/предупреждения и не получить вообще ничего на странице - это по-вашему выход?
Я попробую деликатно объяснить, почему это происходит.
1. Люди цепляются к вашим примерам, потому что они подаются, как бы это сказать, в несколько вызывающем духе. Всё бы ничего, но на фоне скудной лексики и очевидного незнания или неприятия определённых правил, стандартов и паттернов программирования - это часто звучит провоцирующе и вызывает желание потроллить (т.е. как-то поддеть). Справедливости ради стоит отметить, что вы всё же пишете какой-то там работающий код, но игнорируете факторы унификации кода. Т.е. - вы пишете для себя, как вам привычно/удобно.
2. Есть такое слово - ретроград. В практическом понимании - это человек, не желающий развиваться и цепляющийся за устаревшие, отработавшие и исчерпавшие себя понятия/концепции/методики, с помощью которых пытается решать насущные задачи. К сожалению, это относится и к вам. Вы застряли где-то на уровне примеров процедурных PHP-скриптов из мануалов и упорно не желаете сходить с этой точки. Между тем, современные фреймворки и прочие платформы разработки уже давно требуют значительно более широких и системных знаний.
3. Вы также не заботитесь о мало-мальском стиле кодирования, это очевидно по всем вашим примерам. А между тем, и в Друпале и в целом в PHP есть ряд довольно жёстких норм и соглашений даже о форматировании кода. Которых придерживаются (представьте себе) чуть менее, чем все обитатели этого форума. Даже если этого не хочется. Опять же, у вас это выглядит забавным контрастом с общепринятыми индустриальными стандартами. Особенно на фоне ваших заявлений о вашем опыте и "я могу".
К сожалению, в совокупности пп.1-3 оставляют впечатление какого-то блаженного чудака. Пишу это не с желанием задеть вас, а с целью облегчить вам процесс вливания в дружное и весёлое сообщество друпаллургов. Надеюсь, у вас получится.
Всё прочитать не смог - слишком много букв.
Ну как бы это и не ожидалось с первого подхода. Не переживайте.