За последние 24 часа нас посетили 15611 программистов и 1552 робота. Сейчас ищут 880 программистов ...

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

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

  1. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.861
    Симпатии:
    657
    Зачем различать $title, $content и прочие $var при передаче?

    Это, конечно, можно использовать для всяких второстепенных кусочков, но в общем часто используется иерархия шаблонов «снизу вверх». Принцип работы «на пальцах» показан в конце этой статьи: https://gency.ru/g-drive-quick-start (часто отрендеренные блоки делаются доступными по уник. id/ключу для выше стоящих шаблонов; замена значения переменной content – это фишка конкретного движка).
    --- Добавлено ---
    И не лепите _once бездумно ;)
    --- Добавлено ---
    «Справочники» можно передавать, как вложенные массивы, если хотите структурно различать «основные переменные» страницы и «справочники» (и вы ограничились использованием только одного массива).
     
    viktor72 нравится это.
  2. viktor72

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

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Потому что не видел альтернативного варианта. Сейчас задумался. Альтернативы? Внести все эти значения в один массив...Смущает, что самые разные данные упаковываются в один массив. другого выхода пока не вижу. Или же архитектурно по другому, но я ещё этого не вижу.
    Перечитал три раза, пока что не смог постичь . Пошел исктать туториалы "архитектура view". Спасибо

    Я задумался. Не могу понять , что противопоставать.
     
  3. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.861
    Симпатии:
    657
    См. приписку из пред. поста: доп. массивы оформляйте, как вложенные массивы или объекты.

    Сначала отрендери дочерний шаблон, потом воткни результат в родительский (который тоже можно отрендерить).

    «Плохо» задумались. Там нечего понимать :)
     
    viktor72 нравится это.
  4. viktor72

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

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Мозг человека организован так, что в процессе осознания объекта в сознании появляется образ (класс, сущность). После этого между ячейками памяти в мозге появляются нейронные связи(методы). И при упоминании какого либо слова в сознании человека появляется образ и понимание назначения этого предмета. Это происходит мнгновенно. Если значение слова не понятно, то мозг отказывает в формировании образа и не формируется его назначение(методы).

    У меня сформировался набор слов и выражений из текста выше, которые не могут сформировать образы и нейронные связи по поводу этих сущностей. я их выделил в массив:
    [
    второстепенные кусочки,
    иерархия шаблонов,
    иерархия шаблонов снизу вверх,
    отрендировать,
    отрендированные блоки,
    основные переменные,
    структурно различать,
    ]

    Если можете что то объяснить,
    то спасибо;
    если нет,
    то спасибо за внимание.
     
  5. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    • отрендировать - в нашем контексте - перевести в данные в HTML-формат, чтоб их мог отобразить браузер
    • отрендированные блоки - соответственно, блоки, в которых после определённого процесса не осталось переменных, а стал чистый HTML
    • структурно различать - понимать разницу между разными элемента
    • иерархия - соотношение, кто родительский, а кто дочерний
    • снизу вверх - от дочерних к родительским
    • второстепенные кусочки - не знаю, что автор имел в виду :)))
     
    viktor72 нравится это.
  6. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.861
    Симпатии:
    657
    В рамках иерархии «снизу вверх», конечно, можно делать исключения и подключать одни шаблоны внутри др. обычным способом вроде <?php include __DIR__.'/blocks/block100500.php'; ?>, чтобы не дублировать код, не делать шаблоны слишком громоздкими и т.п.
     
    viktor72 нравится это.
  7. viktor72

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

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Не хватает информации для формирования образов

    Предварительные выводы:
    - существуют html -шаблоны и они вкладываются один в другой (иерархия);
    - инклуд используется не как правило а как исключение;
    Значит, вместо инклуда используется создание объектов класса в котором создаются шаблоны. То есть, в методах класса из html- тегов собираются шаблоны. При таком допущении в папке views лежат классы которые собирают из деталей шаблонов страницы.

    Правильно ли я сделал вывод?

    Чтоб расширить в мозге картину ищу в поиске информация по следующим тегам:
    "рендер php",
    "php view страницы",
    "php шаблоны"
    Правильные ли запросы я сформировал? Если нет, подскажите.
    Спасибо.
     
  8. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.861
    Симпатии:
    657
    Нет. Для рендеринга достаточно элементарной ф-ции. Просто, чтобы не вызывать ее в контроллере несколько раз, ее можно сделать посложнее. Например, чтобы при вызове с дочерним шаблоном в параметре, в котором прописана связь с родительским, она автоматом обрабатывала все связанные «снизу вверх» шаблоны (ограничителем рекурсии может быть какое-то спец. значение в качестве имени шаблона или, например, одно и то же имя/отсутствие изменения имени на двух соседних уровнях иерархии).
    --- Добавлено ---
    Конечно, эта функция может быть частью класса представления, но функции представления часто не оборачиваются в класс, либо методы этого представления оборачиваются в обычные ф-ции. А в папке views обычно лежат только шаблоны. Из-за этого многие даже путают/смешивают понятия «шаблон» и «представление».
     
    viktor72 нравится это.
  9. viktor72

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

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Пока что не могу полностью осознать.
    Нашел пример на https://htmlacademy.ru/tutorial/php/templates, но там нет функции и массива. Пытаюсь разгадать содержание функции и массива.
    Вот код с сайта:
    в лейаут выносим общий HTML-код
    layout.php
    PHP:
    1. <!DOCTYPE html>
    2.   <html lang="ru">
    3.   <head>
    4.     <title><?= $title; ?></title>
    5.     <link rel="stylesheet" href="css/style.css">
    6.   </head>
    7.   <body>
    8.     <header class="main-header">
    9.       <h1 class="visually-hidden">Дневник погоды</h1>
    10.     </header>
    11.     <div class="main-content">
    12.       <main class="content"><?= $content; ?></main>
    13.     </div>
    14.     <footer class="main-footer">
Дневник наблюдения за погодой. Все права защищены</footer>
    15.   </body>
    16. </html>
    Теперь очередь за шаблоном страницы:
    [main.php]
    PHP:
    1. <div class="content__main-col">
    2.   <h2 class="visually-hidden">Последние записи</h2>
    3.   <a class="button" href="/gif/add">Добавить новую</a>
    4.  
    5.   <ul class="items-list">
    6.     <?php foreach ($items as $item): ?>
    7.       <?=renderTemplate('inc/item.php', ['item' => $item]);?>
    8.     <?php endforeach; ?>
    9.   </ul>
    10. </div>
    А вот и шаблон блока для показа одной записи:
    [inc/item.php]
    PHP:
    1. <li class="list-item">
    2.   <div class="picture">
    3.     <img src="uploads/preview_<?=$item['path'];?>">
    4.   </div>
    5.   <h3 class="desc-title">
    6.     <a href="/view?id=<?=$item['id'];?>"><?=$item['title'];?></a>
    7.   </h3>
    8.   <div class="desc-data">
    9.     <span class="temp"><?=$item['temp'];?></span>
    10.   </div>
    11. </li>
    index.php:
    PHP:
    1. <?php
    2. // двумерный массив со списком записей
    3. $items_list = [];
    4.  
    5. // HTML код главной страницы
    6. $page_content = renderTemplate('main.php', ['items' => $items_list]);
    7.  
    8. // окончательный HTML код
    9. $layout_content = renderTemplate('layout.php',
    10. ['content' => $page_content, 'title' => 'Дневник наблюдений за погодой']);
    11.  
    12. // вывод на экран итоговой страницы
    13. print($layout_content);
    Это я пытаюсь додумать содержимое функции и массива:
    PHP:
    1. function renderTemplate($a, $b = array())
    2. {  
    3.     // ??????
    4.     include $a;
    5.    
    6. }
    7.  
    8. //
    9. $items_list = [
    10.     'items'=>[
    11.         'path'=>'test path',
    12.         'id'=>'test id',
    13.         'title'=>'test itle',
    14.         'temp'=>'test temp'
    15.         ],
    16.     'content'=>'????',
    17.     'title'=>['title'=>'title']  
    18.     ];
    Интуитивно чувствую что ответ очень прост, но не получается. Ещё возникает вопрос - а если на одну страницу надо передать множество блоков, скажем штук 10 , такая модель может работать?
     
  10. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.861
    Симпатии:
    657
    https://php.ru/forum/posts/623953/
    https://php.ru/forum/posts/561579/

    Вот из последнего (на ветвление не обращайте внимания, т.е. делайте без него в ф-ции, о чем мы говорили):
    PHP:
    1. if ($r0['bits']&48)
    2. {
    3.   ob_start();
    4.   require PATH.$r0['module'].'.php';
    5.   $page['content']=ob_get_clean();
    6. }
    7.  
    8. require PATH.$layout.'.php';
    Типа во вложенном можно написать «$layout = 'layout';», задав связь с родителем, о чем я выше писал.
    --- Добавлено ---
    Конечно. Почему нет?
     
    #35 miketomlin, 7 июн 2021
    Последнее редактирование: 8 июн 2021
    viktor72 нравится это.
  11. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.861
    Симпатии:
    657
    Только нужно четко ответить на вопрос, зачем рендерить отдельно. В вашем примере с циклом форыч достаточно обычного include ;) Это как раз тот самый «второстепенный кусочек», который может рендериться обычным путем сверху вниз.
    --- Добавлено ---
    А вот, например, виджеты сайдбара можно рендерить отдельно в отдельном процессе и сохранять разметку в файловом кеше, а потом просто считывать эти файлы в отдельные переменные, которые передаются в родительский шаблон.
     
    viktor72 нравится это.
  12. Walk

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

    С нами с:
    7 сен 2008
    Сообщения:
    452
    Симпатии:
    86
    Привет любителям велосипедов! :D

    Писал как-то свой MVC-фреймворк, можно посмотреть примеры кода:

    Контроллер:
    https://github.com/WalkWeb/DW-Framework/blob/master/controllers/PostController.php#L46

    Рендер вьюхи:
    https://github.com/WalkWeb/DW-Framework/blob/master/src/NWFramework/Controller.php#L62

    P.S.
    Добавьте автозагрузку классов и использование use Models/CityModel

    Подгружать классы через include это уж совсем прошлый век.
     
    viktor72 нравится это.
  13. viktor72

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

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Перечитываю в 10 раз... не могу осознать
     
  14. viktor72

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

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Возможно надо сделать шаг назад в обучении и проработать рекурсию и многомерные массивы? или что я не понимаю,.. не понимаю?
     
  15. viktor72

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

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    рендеринг и шаблонизация в чём различие? чем различаются эти понятия?
     
  16. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Рендеринг - преобразование шаблона в готовый html, мы же уже об этом говорили. Шаблонизация - грубо говоря, создание этих самых шаблонов.
     
    viktor72 нравится это.
  17. viktor72

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

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    Спасибо. Хожу по кругу.
    Динамически? или мне надо создать 10 блоков для вывода разного из базы в каждом блоке - я создаю , то есть занимаюсь шаблонизацией. создал эти блоки значит у меня создан шаблонизатор. и в рендере эти блоки вставляются каждый в своё место. И получается :
    ?
    Я наконец правильно понял терминологию?
     
  18. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Ну да. А за рендерер у нас сам PHP в принципе, мы только говорим ему какие переменные в какой шаблон подставить.
     
    viktor72 нравится это.
  19. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.861
    Симпатии:
    657
    Ну, посмотрите для примера на приведенный мной код с двумя шаблонами (там подключение второго не обернуто ob_-ф-циями по опред. причинам, но вы представьте, что обернуто). Чтобы не вызывать в контроллере два раза ф-цию (по разу для каждого шаблона), можно сделать ф-цию, которая бы при вызове с указанием в параметре только дочернего шаблона рендерила и дочерний, и родительский. Связь с родительским тупо прописывается в дочернем.

    Если по-прежнему не понятно, пока забейте. Делайте в лоб:
    PHP:
    1. $result = render('layout', ['content' => render('template', $page)] + $page);
    или
    PHP:
    1. $result = render('layout', array_merge($page, ['content' => render('template', $page)]));
     
    viktor72 нравится это.
  20. viktor72

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

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    просмотрел материалы на тему создания шаблонизатора . Вот что у меня в результате получилось:
    PHP:
    1. function render($tpl, $var)
    2. {
    3.     if(file_exists($tpl)){
    4.         ob_start();
    5.         extract($var);
    6.         require $tpl;
    7.         return ob_get_clean();
    8.     }
    9.    
    10. }
    11. $menu = render('menu.php', ['cat'=>$cat]);
    12.  
    13. $main = render('main.php', ['menu'=>$menu, 'content_main'=>$content_main]);
    14.  
    15. $content = render('content.php', ['content'=>$main, 'title'=>'My Render', 'result'=>$res]);
    16.  
    17. echo $content;
    Какие достоинства и недостатки такой систем? Как улучшить или есть принципиально лучший вариант?
     
  21. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Контроллер слишком много знает о шаблонах.
     
    viktor72 нравится это.
  22. viktor72

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

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    В чём риски\проблемы? :
    1. угроза безопасности приложения?
    2. негативное влияние на скорость работы приложения?
    3. противоречит принципам mvc и при командой работе вызовет раздражение
    4. впоследствии будет трудно найти
    5. другое.
     
  23. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.861
    Симпатии:
    657
    Ну, например, что там за меню? Если это сквозное меню сайта, контроллер о нем знать не должен.

    См., что я выше писал про виджеты сайдбара. С меню аналогично.
     
    viktor72 нравится это.
  24. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    @viktor72 Везде дублирование кода будет.
    https://platesphp.com/ - вот смотри тут, фактически, необходимый минимум для нормальной шаблонизации на чистом PHP.
    --- Добавлено ---
    Если аналог не потянешь, подойдёт включать всякие там меню прямо в шаблоне через include
     
    viktor72 нравится это.
  25. viktor72

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

    С нами с:
    20 дек 2015
    Сообщения:
    326
    Симпатии:
    6
    ничего не понимаю.
    --- Добавлено ---
    английский слабо знаю. гугл перевел своеобразно. Это готовый шаблонизатор. я хочу разобраться как всё работает, пока не хочу использовать готовое решение. Спасибо.