Имеется страница-форма в которую вносятся данные для создания сущности (создание компании, регистрация в базе данных компании). У компании такие свойства: 1. название, 2. город в которой находится компания. В форме название вводится в поле а город выбирается из выпадающего списка. Города достаются из базы данных. Как в условиях mvc передать на страницу form.php(view) данные из базы ModelCity.php (из справочника городов)? PHP: class CityModel { // достаю из базы данных все города } class CompanyController { $this->view->render('company/form'); } form.php PHP: <form action="companyController" method="post"> <input type="text" name="name" placeholder="Название компании"> <select // название городов> <?php foreach(//.....){ //............}?> </select>
В рамках концепции MVC контроллер - связующее звено между моделью и вьюхой. Он должен взять данные у модели, передать во вьюху.
Уточню: model - CompanyModel controller - CompanyController view - company/form.php Это линейка относящаяся к объекту - Company Но есть ещё объект справочник - City (в котором список городов): model - CityModel controller - CityController (?) view - (?) Из модели City передать данные справочника в другой объект Company во вью. Как корректно это сделать? Создавать объект в CompanyModel (в логику) или CompanyController или совсем по хамски в форме во вью?
Вот только хамить не надо Какие данные нужны, к той модели и обращайтесь --- Добавлено --- Смотрите, если у вас в форме динамически идет подгрузка городов, такой контроллер нужен. Иначе не фантазируйте.
Вопрос - создать объект CityModel прям в контроллере CompanyController или сначала создать объект CityModel в контроллере CityController а потом CityController создать в контроллере компании? уместно ли доставать из базы в чужом контроллере? PHP: class CompanyController { function getForm() { include 'models/CityModel.php'; $model = new CityModel; // ... достаю все города из модели и передаю в вью // $city = ............ $this->view->render('company/form', $city); } } или PHP: class CityController { function getCity() { // в контроллере City создаю модель которая достает все города include 'models/cityModel.php'; $city = new CityModel; // достаю из базы все города return $result; } } class CompanyController { function getForm() { // в контроллере компании создаю форму для создания компании и передаю в неё контроллер городов include 'controllers/CityController.php'; $city = new CityController; $this->view->render('company/form', $city); } }
@viktor72, контроллеры не бывают "чужие", нет такого принципа, что контроллер нужно связывать только с одной моделью. Хотя лучшее решение - создать ещё один класс, сервис, в котором вызывать нужные модели. И сервис использовать в разных контроллерах. Раз уж пилишь MVC, почитай про автозагрузку, а то с инклюдами запаришься. И про PSR-0, PSR-4
- Как логично и как просто! Жалею, что сам не догадался. Создать класс некий посредник между моделями\справочниками и всеми контроллерами. Только теперь думаю в какую папку логичнее разместить - core, config, rouets... или другой какой. Пока что мне логичнее кажется в routes С инклюдами я сам интуитивно чувствовал, что так не должно быть. Спасибо за рекомендациями.
Вообще, лучше рассматривать модели ни как классы, а как весь слой работы с данными. По поводу сервисов - ну я в папку service кидаю.
Под этими номерами как раз правила автозагрузки описаны В принципе можно придумать и свои, чтобы для начала хотя бы просто было.
Сразу же полез смотреть тему. .. spl_autoload_register();... пока что не могу понять в каком файле\классе создавать объекты моделей чтоб они потом попадали внутрь контроллеров ... значит я ещё чего то не понимаю.. Мои рассуждения - существует некий файл autoload.php , в нём spl_autoload_register(), и создаются модели - new xxxModel. И этот файл инклудится в каждом конструкторе всех контроллеров... Насколько правильно моё рассуждение? Спасибо.
Существует один файлик autoload.php, который инклюдится один раз в главный индексный файл, после чего можно не задумываться о том, чтоб куда-то включать файлы, они включаются сами. Кстати, надеюсь, у тебя есть единая точка входа?
Да, index.php. Подключил, работает. PHP: spl_autoload_register(function ($class_name) { include_once 'core/'.$class_name . '.php'; }); Но - проблема в том, что подключил только папку CORE . а ещё надо подключить папку models. Предположение - 1. архитектура не правильная, 2. функция spl_autoload_register() не правильно организован. Или в чём то другом проблема?
Сижу изучаю psr и пространство имён. Спасибо. НО.. вопрос Я вывел регионы как и хотел PHP: class ResumeController{ function __construct() { parent::__construct(); $this->region = new region; } function getFormResume() { $var = $this->region->selectAll(); $this->view->render('My form resume','resume/form', $var); ...... Если мне надо передать данные не из одного справочника "регионы" а из большого количества. например: 1.регионы, 2. пол, 3. язык, 4. валюта, 5. цвет глаз ... и т.д. ... В моём варианте это бы выглядело так: PHP: $this->view->render('My form resume','resume/form', $var, $var2, $var3, $va4, $var5); а если параметров 10 или 20...? предполагаю есть решение лучшее для передачи данных ... Я конечно могу запаковать в массив, но потом его придётся распаковывать во вьюхе.. Есть какое то лучшее решение?
Сделал. Работает. Спасибо. Мне на будущее - Как большие сайты решают эту проблему? То есть, допустим на сайте надо создать сущность (например коммерческую компанию) и в файл - форму регистрации необходимо передать 10-20 пакетов данных из справочников (для выпадающих списков). Они тоже будут передавать через рендер? PHP: $this->view->render('folder/index', $var); В какую сторону мне смотреть для развития?
Ну запаковать эти 10-20 пакетов в массив ничего не стоит. Я на одном проекте, где справочники были типовые по структуре, их было много, но в каждом не слишком много элементов, просто загнал все в одну таблицу и радовался. Но я точно знал, что там не будет тысячи элементов, и что структура очень маловероятно, что изменится. Поля были ref_type, ref_id, name --- Добавлено --- Ключ - составной
Спасибо. Откуда этот вопрос у меня возник - распаковка массивов во views это небольшие логические действия, что как бы противоречит концепции mvc . Всё время возникает вопрос - где грань между логикой и контроллером и представлением? К чему привыкать , чтоб в дальнейшем при работе с другими програмистами не возникало вопросов.
Ну распаковкой обычно занимается не сам код шаблона, а выше, код того класса View, в который вы это передаёте. И выглядит это приблизительно так: PHP: public function render(string $viewFile, array $arguments) { extract($arguments); include($viewFile); } Ну это грубо и упрощённо, но сам принцип такой. --- Добавлено --- А вообще, на реальном проекте вы вряд ли будете делать всю эту фигню с нуля. Обычно берутся или фреймворки, или независимые пакеты. С нуля - это хорошее упражнение.
Сделал. Как просто и логично. Спасибо. Организовал так: тут упаковываю в массив: PHP: class Service { function getClass() { // создаю объекты - справочники : города, должности, пол и т.д. $result = ['region'=>$region, ......]; return $result; } } в родительском контроллере создаю объект в котором все справочники из базы: PHP: class controller { function __construct() { $this->service = new Service; $this->view = new view; } } контроллер страницы, дочерний PHP: class childController extends Controller { function __construct() { parent::__construct(); } // выдает форму создания function getForm() { $var = $this->service->getService(); $this->view->render('child/form', $var); } } не уверен что проверку и распаковку надо делать во вью PHP: class view { function render($content, $var=false) { // распаковываю все справочники if(!empty($var)) { extract($var); } include_once 'views/template.php'; } } Раньше не использовал функцию extract(); - изучил. Начал использовать. Спасибо. Предполагаю, перед тем как использовать фреймворк надо разобраться как он работает изнутри. В моей схеме я что то пропустил? Есть более логичное, правильное решение?
Ну я сразу начал, с тогда ещё живого Kohana, свой не писал, времени не было. Но в исходники используемых фреймворков иногда заглядываю. ну сделали правильно, за исключением того, что вьюха у вас захардкожена. У меня нет
Я начал изучать Laravel . Много вопросов - не знаю синтаксиса blade . Не знаю с какой стороны к нему подступится. Как на нём делать авторизацию и прочее.. вообщем освоино 1-2% от необходимого . Это иззи проверки во вью, в чём то ещё? В чём грех? PHP: if(!empty($var)){ extract($var); } include_once 'views/template.php';
Я про это Ну я свободно читаю на тех. английском, так что https://laravel.com/docs/8.x - и всё понятно. Английский уровня от Intermediate для профессии обязателен
Если про инклуд, то я в процессе изучения пространства имён и автозаргузки. Если про код, архитектуру.. построино так: в рендер передается тайтл, путь страницы , и значения справояников $content = 'folder/page'; PHP: function($title, $content, $var){ передается в шаблон (template.php) template.php PHP: <header> <?php echo $title; ?> </header> <main> <?php // подгружается страница , в неё передается всё из $var iclude_once $content. '.php'; ?> </main> <footer> </footer> В чём кроется зло? Английский изучаю. В процессе. Пока что слушаю и читаю туториалы и мануал на русском. Спасибо.