За последние 24 часа нас посетили 21466 программистов и 1066 роботов. Сейчас ищут 813 программистов ...

mvc - как передать из справочника в view?

Тема в разделе "PHP для новичков", создана пользователем viktor72, 20 май 2021.

  1. viktor72

    viktor72 Активный пользователь

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Имеется страница-форма в которую вносятся данные для создания сущности (создание компании, регистрация в базе данных компании).

    У компании такие свойства: 1. название, 2. город в которой находится компания.

    В форме название вводится в поле а город выбирается из выпадающего списка.
    Города достаются из базы данных.

    Как в условиях mvc передать на страницу form.php(view) данные из базы ModelCity.php (из справочника городов)?


    PHP:
    1. class CityModel
    2. {
    3.     // достаю из базы данных все города
    4. }
    5.  
    6. class CompanyController
    7. {
    8.     $this->view->render('company/form');
    9. }
    form.php
    PHP:
    1. <form action="companyController" method="post">
    2.     <input type="text" name="name" placeholder="Название компании">
    3.     <select // название городов>
    4.          <?php foreach(//.....){ //............}?>
    5.     </select>
     
  2. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    В рамках концепции MVC контроллер - связующее звено между моделью и вьюхой. Он должен взять данные у модели, передать во вьюху.
     
  3. viktor72

    viktor72 Активный пользователь

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Уточню:
    model - CompanyModel
    controller - CompanyController
    view - company/form.php
    Это линейка относящаяся к объекту - Company

    Но есть ещё объект справочник - City (в котором список городов):
    model - CityModel
    controller - CityController (?)
    view - (?)
    Из модели City передать данные справочника в другой объект Company во вью.
    Как корректно это сделать? Создавать объект в CompanyModel (в логику) или CompanyController или совсем по хамски в форме во вью?
     
  4. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
    Вот только хамить не надо :)

    Какие данные нужны, к той модели и обращайтесь ;)
    --- Добавлено ---
    Смотрите, если у вас в форме динамически идет подгрузка городов, такой контроллер нужен. Иначе не фантазируйте.
     
    viktor72 нравится это.
  5. viktor72

    viktor72 Активный пользователь

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Вопрос - создать объект CityModel прям в контроллере CompanyController или сначала создать объект CityModel в контроллере CityController а потом CityController создать в контроллере компании?

    уместно ли доставать из базы в чужом контроллере?
    PHP:
    1. class CompanyController
    2. {
    3.     function getForm()
    4.     {
    5.          include 'models/CityModel.php';
    6.          $model = new CityModel;
    7.          // ... достаю все города из модели и передаю в вью
    8.         // $city = ............
    9.         $this->view->render('company/form', $city);
    10.      }
    11. }
    или
    PHP:
    1. class CityController
    2. {
    3.     function getCity()
    4.     {
    5.       // в контроллере City создаю модель которая достает все города
    6.        include 'models/cityModel.php';
    7.        $city = new CityModel;
    8.        // достаю из базы все города
    9.        return $result;
    10.     }
    11. }
    12.  
    13. class CompanyController
    14. {
    15.     function getForm()
    16.     {
    17.         // в контроллере компании создаю форму для создания компании и передаю в неё контроллер городов
    18.          include 'controllers/CityController.php';
    19.          $city = new CityController;
    20.          $this->view->render('company/form', $city);
    21.     }
    22. }
     
  6. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    @viktor72, контроллеры не бывают "чужие", нет такого принципа, что контроллер нужно связывать только с одной моделью. Хотя лучшее решение - создать ещё один класс, сервис, в котором вызывать нужные модели. И сервис использовать в разных контроллерах.


    Раз уж пилишь MVC, почитай про автозагрузку, а то с инклюдами запаришься. И про PSR-0, PSR-4
     
    viktor72 нравится это.
  7. viktor72

    viktor72 Активный пользователь

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    - Как логично и как просто! Жалею, что сам не догадался. Создать класс некий посредник между моделями\справочниками и всеми контроллерами. Только теперь думаю в какую папку логичнее разместить - core, config, rouets... или другой какой. Пока что мне логичнее кажется в routes

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

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Вообще, лучше рассматривать модели ни как классы, а как весь слой работы с данными.

    По поводу сервисов - ну я в папку service кидаю.
     
    viktor72 нравится это.
  9. viktor72

    viktor72 Активный пользователь

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Написано красиво, но технически что это значит?

    А с PSR что не так? я вроде стараюсь соблюдать
     
  10. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
    :) Под этими номерами как раз правила автозагрузки описаны ;) В принципе можно придумать и свои, чтобы для начала хотя бы просто было.
     
    viktor72 нравится это.
  11. viktor72

    viktor72 Активный пользователь

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Сразу же полез смотреть тему. .. spl_autoload_register();... пока что не могу понять в каком файле\классе создавать объекты моделей чтоб они потом попадали внутрь контроллеров ... значит я ещё чего то не понимаю..
    Мои рассуждения - существует некий файл autoload.php , в нём spl_autoload_register(), и создаются модели - new xxxModel. И этот файл инклудится в каждом конструкторе всех контроллеров... Насколько правильно моё рассуждение? Спасибо.
     
  12. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Существует один файлик autoload.php, который инклюдится один раз в главный индексный файл, после чего можно не задумываться о том, чтоб куда-то включать файлы, они включаются сами. Кстати, надеюсь, у тебя есть единая точка входа?
     
    viktor72 нравится это.
  13. viktor72

    viktor72 Активный пользователь

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Да, index.php.
    Подключил, работает.
    PHP:
    1. spl_autoload_register(function ($class_name) {  
    2.     include_once 'core/'.$class_name . '.php';
    3.    
    4. });
    Но - проблема в том, что подключил только папку CORE . а ещё надо подключить папку models. Предположение - 1. архитектура не правильная, 2. функция spl_autoload_register() не правильно организован. Или в чём то другом проблема?
     
  14. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Ну поэтому я и говорил про PSR. Там описан принцип преобразования пространств имён в папки
     
  15. viktor72

    viktor72 Активный пользователь

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Сижу изучаю psr и пространство имён. Спасибо.

    НО.. вопрос

    Я вывел регионы как и хотел

    PHP:
    1. class ResumeController{
    2. function __construct()
    3.     {
    4.         parent::__construct();
    5.         $this->region = new region;
    6.     }
    7.  
    8. function getFormResume()
    9.     {
    10.         $var = $this->region->selectAll();
    11.         $this->view->render('My form resume','resume/form', $var);
    12. ......
    Если мне надо передать данные не из одного справочника "регионы" а из большого количества. например: 1.регионы, 2. пол, 3. язык, 4. валюта, 5. цвет глаз ... и т.д. ... В моём варианте это бы выглядело так:
    PHP:
    1. $this->view->render('My form resume','resume/form', $var, $var2, $var3, $va4, $var5);
    а если параметров 10 или 20...? предполагаю есть решение лучшее для передачи данных ... Я конечно могу запаковать в массив, но потом его придётся распаковывать во вьюхе..
    Есть какое то лучшее решение?
     
  16. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Запаковать в массив и не париться.
     
    viktor72 нравится это.
  17. viktor72

    viktor72 Активный пользователь

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Сделал. Работает. Спасибо.
    Мне на будущее - Как большие сайты решают эту проблему? То есть, допустим на сайте надо создать сущность (например коммерческую компанию) и в файл - форму регистрации необходимо передать 10-20 пакетов данных из справочников (для выпадающих списков). Они тоже будут передавать через рендер?
    PHP:
    1. $this->view->render('folder/index', $var);
    В какую сторону мне смотреть для развития?
     
  18. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Ну запаковать эти 10-20 пакетов в массив ничего не стоит. Я на одном проекте, где справочники были типовые по структуре, их было много, но в каждом не слишком много элементов, просто загнал все в одну таблицу и радовался. Но я точно знал, что там не будет тысячи элементов, и что структура очень маловероятно, что изменится.
    Поля были ref_type, ref_id, name
    --- Добавлено ---
    Ключ - составной
     
    viktor72 нравится это.
  19. viktor72

    viktor72 Активный пользователь

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Спасибо. Откуда этот вопрос у меня возник - распаковка массивов во views это небольшие логические действия, что как бы противоречит концепции mvc . Всё время возникает вопрос - где грань между логикой и контроллером и представлением? К чему привыкать , чтоб в дальнейшем при работе с другими програмистами не возникало вопросов.
     
  20. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Ну распаковкой обычно занимается не сам код шаблона, а выше, код того класса View, в который вы это передаёте. И выглядит это приблизительно так:
    PHP:
    1. public function render(string $viewFile, array $arguments) {
    2.     extract($arguments);
    3.     include($viewFile);
    4. }
    Ну это грубо и упрощённо, но сам принцип такой.
    --- Добавлено ---
    А вообще, на реальном проекте вы вряд ли будете делать всю эту фигню с нуля. Обычно берутся или фреймворки, или независимые пакеты. С нуля - это хорошее упражнение.
     
    viktor72 нравится это.
  21. viktor72

    viktor72 Активный пользователь

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Сделал. Как просто и логично. Спасибо.
    Организовал так:

    тут упаковываю в массив:
    PHP:
    1. class Service
    2. {
    3.     function getClass()
    4.     {
    5.         // создаю объекты - справочники : города, должности, пол и т.д.
    6.         $result = ['region'=>$region, ......];
    7.         return $result;
    8.     }
    9. }
    в родительском контроллере создаю объект в котором все справочники из базы:
    PHP:
    1. class controller
    2. {  
    3.     function __construct()
    4.     {
    5.         $this->service = new Service;
    6.         $this->view = new view;  
    7.     }
    8. }
    контроллер страницы, дочерний
    PHP:
    1. class childController extends Controller
    2. {  
    3.     function __construct()
    4.     {
    5.         parent::__construct();
    6.     }
    7.    
    8.     // выдает форму создания
    9.     function getForm()
    10.     {
    11.         $var = $this->service->getService();
    12.                
    13.         $this->view->render('child/form', $var);
    14.     }
    15. }

    не уверен что проверку и распаковку надо делать во вью
    PHP:
    1. class view
    2. {
    3.     function render($content, $var=false)
    4.     {
    5.         // распаковываю все справочники
    6.         if(!empty($var))
    7.        {
    8.             extract($var);
    9.         }
    10.         include_once 'views/template.php';
    11.      }
    12. }
    Раньше не использовал функцию extract(); - изучил. Начал использовать. Спасибо.

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

    В моей схеме я что то пропустил? Есть более логичное, правильное решение?
     
  22. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Ну я сразу начал, с тогда ещё живого Kohana, свой не писал, времени не было. Но в исходники используемых фреймворков иногда заглядываю.

    ну сделали правильно, за исключением того, что вьюха у вас захардкожена. У меня нет
     
  23. viktor72

    viktor72 Активный пользователь

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Я начал изучать Laravel . Много вопросов - не знаю синтаксиса blade . Не знаю с какой стороны к нему подступится. Как на нём делать авторизацию и прочее.. вообщем освоино 1-2% от необходимого .

    Это иззи проверки во вью, в чём то ещё? В чём грех?
    PHP:
    1. if(!empty($var)){
    2.             extract($var);
    3.         }
    4.         include_once 'views/template.php';
     
  24. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Я про это
    Ну я свободно читаю на тех. английском, так что https://laravel.com/docs/8.x - и всё понятно. Английский уровня от Intermediate для профессии обязателен
     
  25. viktor72

    viktor72 Активный пользователь

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Если про инклуд, то я в процессе изучения пространства имён и автозаргузки.
    Если про код, архитектуру.. построино так:
    в рендер передается тайтл, путь страницы , и значения справояников
    $content = 'folder/page';
    PHP:
    1. function($title, $content, $var){
    передается в шаблон (template.php)
    template.php
    PHP:
    1. <header>
    2.     <?php echo $title; ?>
    3. </header>
    4. <main>
    5.     <?php
    6.         // подгружается страница , в неё передается всё из $var
    7.          iclude_once $content. '.php';
    8.     ?>
    9. </main>
    10. <footer>
    11. </footer>
    В чём кроется зло?

    Английский изучаю. В процессе. Пока что слушаю и читаю туториалы и мануал на русском. Спасибо.