За последние 24 часа нас посетили 22723 программиста и 1262 робота. Сейчас ищут 740 программистов ...

Буферизация вывода и быстрые шаблоны

Тема в разделе "PHP для новичков", создана пользователем 440Hz, 11 авг 2006.

  1. D.Lans

    D.Lans Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    345
    Симпатии:
    0
    Mavir ясно.
    Эта идея натолкнула меня на мысли.
    В общем почти так и сделал.
    Вроде работает.
    Сенк. :)
     
  2. Hight

    Hight Старожил
    Команда форума Модератор

    С нами с:
    5 мар 2006
    Сообщения:
    7.153
    Симпатии:
    0
    Адрес:
    из злой параллельной вселенной
    jсda
    svk
    горячие парни 8)
     
  3. D.Lans

    D.Lans Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    345
    Симпатии:
    0
    Итак, возникла проблема.
    В шаблоне я указываю такую штуку:
    {php_register}
    В шаблонизаторе задаю, чтобы при ее нахождении она менялась на результат выполнения PHP файла.
    Сам PHP файл я подключаю require().
    Однако есть проблема.

    В итоге получается вот что:
    Код (Text):
    1.  
    2. Поздравляем, регистрация прошла успешно<br><br><br><html>
    3. <head>
    4.   <title>Lans CMS -> Страничка регистрации. Шаг 2.</title>
    5. <link rel="stylesheet" type="text/css" href="skins/main/css/main.css">
    6. </head>
    7. <body>
    8. </body>
    9. </html>
    То бишь надпись об успешной регистрации вылазит не между тегами <body> </body> а где-то вообще вверху файла.
    Я подозреваю, это происхожит потому что при выполнении оператора require() он не записывает результат выполнения в отдельную переменную (чтобы потом вставить его в нужное место в HTML файле) а сразу выводит его, так что получается что надпись об успешной регистрации выше чем надо..

    Как это пофиксить?

    Или как записатб результат выполнения файла в отдельную строковую перменную?
    Если ли для этого специализированные функции?
     
  4. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    D.Lans

    проектировать архитектуру приложения надо грамотно.
    сдается мне у тебя с этим проблемы, а шаблоны - это уже следствия.
     
  5. D.Lans

    D.Lans Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    345
    Симпатии:
    0
    Возможно.
    Поэтому в последнее время я решил завести некую документацию.
    В ней описываю как и что работает.
    +перед созданием чего-то относительно большого описываю как оно должно работать.

    Но в данном случае просто я знаю как оно должно работать, но не знаю как реализовать это в коде. :)
     
  6. D.Lans

    D.Lans Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    345
    Симпатии:
    0
    Усе, решил проблему.
    Заюзал буферизацию вывода.

    PHP:
    1.  
    2.    #Загружает результат выполнения файла в единую переменную
    3.   protected function get_include_contents($filename) {
    4.            if (is_file($filename)) {
    5.                    ob_start();
    6.                    include ("$filename");
    7.                    $contents = ob_get_contents();
    8.                    ob_end_clean();
    9.                    return $contents;
    10.            }
    11.            return false;
    12.    }
    13.  
     
  7. D.Lans

    D.Lans Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    345
    Симпатии:
    0
    Офф: а почему PHP код между PHP-тегами не подсвечивается?
     
  8. Mavir

    Mavir Guest

    Надо PHP код обрамлять <? ?>
     
  9. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    до этого всего идет этап проектирвоания самой системы, т.е. что где лежит, что как передается, что и где отрабатывает.

    то, что ты сейчс сделал не более чем затычка, т.к. ИМХО такого не должно происходит в принципе.

    вот расскажи где нить в другом топике об архитектуре твоей системы? просто интересно ...
     
  10. D.Lans

    D.Lans Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    345
    Симпатии:
    0
    Это ты о чем? :shock:

    Долго писать :)
    Может попробую.
     
  11. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    эт я к чему? Эт я к тому, что расписав для себя это (структуру или архитектуру системы), ты поймешь узкие места, которые у тебя есть, а они есть, судя по тому, что ты пишешь и спрашиваешь.

    хотя может тебе просто еще рано про это думать ... ибо никакой системы не существует. а есть разрозненный набор скриптов.
     
  12. D.Lans

    D.Lans Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    345
    Симпатии:
    0
    О, да, они есть.

    Но из-за отсутствия опыта я просто не знаю как можно реализовать лучше те или иные моменты.

    Так что пишу как умею с расчетом на возможное переделывание при повышения опыта.

    Ну не такой уж и разрозненный. :)
    Файлы есть и даже умеют взаимодействовать друг с другом.
    Во всех файлах есть обработка ошибок на самые разные действия.
     
  13. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда

    от! а я про что? только не в этом топике, наверное ...
     
  14. D.Lans

    D.Lans Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    345
    Симпатии:
    0
    440hz
    если я буду писать про все чего я не знаю...

    Ты запаришься читать, а я писать.. :)
     
  15. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    ты попробуй ...
     
  16. D.Lans

    D.Lans Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    345
    Симпатии:
    0
    440hz каждую функцию надо описывать? :shock:
     
  17. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда

    я те толкую не про функции, а про постороение самой системы и о взаимодействии различных ее частей.

    забудь про php-код. думай немного более абстрактно. реализацию оставим на потом.

    вот какие части ты бы мог выделить в своей системе?
     
  18. D.Lans

    D.Lans Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    345
    Симпатии:
    0
    всякие :)

    Во-первых, я пользуюсь твоей основой для системы шаблонов.

    Все разделы сайта определены так:
    site.ru
    site.ru/index.php?act=register
    site.ru/index.php?act=guest

    В файле INDEX.PHP
    -Создаем объект класса шаблонизатора
    -Проверяем GET переменную.
    Если она соответствует предопределенным строкам - передаем в шаблонизатор (template.php), в его свойство ($typePage) зависимости от этого тип страница (тип страницы index.php - 'index', страницы с новостями - 'news'). В остальных случаях просто грузим начальную страницу.
    -Вызываем метод в шаблонизаторе (SendFile()), который грузит нужный файл с шаблоном.
    -Вызываем метод в шаблонизаторе, (parse()) который производит парсинг шаблона.
    -Вызываем метод в шаблонизаторе, (show()) который производит вывод отпарсенной странички.

    Теперь взглянем с другой стороны на работу всего этого, со стороны самого шаблонизатора.

    Работа template.php

    Весь текст (содержимое страничек) хранится в многомерных ассоциативных массивах. Вот пример:

    PHP:
    1.  
    2. <?
    3. var $page = array('index' => array(
    4.                                        '{hello}' => 'Привет!',
    5.                                        '{hello_title}' => 'Доброго времени суток!',
    6.                                        '{now_page}' => 'Главная'),
    7.                      'register' => array(
    8.                                        '{hello_title}' => 'Страничка регистрации',
    9.                                        '{hello}' => 'Спасибо, за ваше желание зарегиcтрироваться!',
    10.                                        '{now_page}' => 'Страничка регистрации'),
    11.                      'register2' => array('{now_page}' => 'Страничка регистрации. Шаг 2.',
    12.                                           '{php_register}' => './modules/register2.php')
    13.     );
    14. ?>
    15.  
    Далее шаблонизатор принимает от index.php тип странички (index, news), записывает его в свое свойство $TypePage.
    Далее методом SendFile() грузим файл с шаблоном (тип_странички.tpl).
    Далее при вызове начинает работать функция парсинга PARSE().
    Она делает много чего.
    Во первых из ассоциативных массивов извлекает те данные, которые одинаковы для всех страниц на сайте (типа копирайта).

    После этого она ищет в файле шаблона переменные, например меню сайта (обозначается как {menu} в шаблоне) и вызывает уже отдельную функцию menu_build() которая генерирует меню (элементы которого (главная, новости, о сайте) хранятся в БД).
    Так же ищется метка {news} в шаблоне - если она найдена, то генерируем блок новостей (функцией news_block()) и подставляем его вместо данной метки.

    Далее она в зависимости от типа страницы ($TypePage) производит определенные действия с шаблоном, который храница все это время в буфере.
    Например для шаблона страница регистрации - выводится форма для введения данных.
    Для второй странички регистрации (в которой происходит проверка данных, которые были введены на первой страничке) в отдельную переменную грузится результат выполнения модуля register2.php которые непосредственно проверяет введенные данные и выводит, произошла ли регистрация или нет.
    Далее эта переменная подставляется в шаблоне второй странички регистрации вместо метки {php_register}

    Когда метод parse() отработал, получаем цельную страничку которую и выводим методом show().

    Усе.

    Конечно длинноватое получилось описание..
    Но думаю суть понятна.
    Позже я хочу ввести такие вещи как кеширование меню и новостей - зачем каждый раз запрашивать их из БД если они обновляются относительно редко.
    Только вот в чем их держать?..
    В текстовом файле?..
     
  19. Border

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

    С нами с:
    22 авг 2006
    Сообщения:
    41
    Симпатии:
    0
    Переделываю сайт на основе шаблонизатора, описанного 440hz.
    В index.php проверяется ID страницы. В зависимости от ID считывается файл конфигурации страницы и, если нужно, подключается обработчик данных из форм страницы. По результатам обработки в буфер из html-шаблонов помещается то или иное основное содержимое странички. Далее буферизуются из шаблонов стандартные для всех страниц элементы. Затем все в сборе выводится в броузер.
    Вот с чем столкнулся. Раньше в html-шаблоне странички, содержащей форму у меня производилась проверка и вывод элемента формы по условиям проверки
    Код (Text):
    1. ...html ...
    2. <?
    3. if (условие) { ?>
    4.     html (элемент формы, например)
    5. <?
    6. }
    7. ?>
    8. ... html ...
    Теперь ничего более умного не придумал, чем производить эту проверку в обработчике страницы, и, если по результатам обработки участок html-шаблона не нужен, то в обработчике создаю две переменных
    PHP:
    1. <?
    2. if (условие) {
    3.     .... ;
    4. }
    5. else {
    6.     $hidden1 = "<!--";
    7.     $hidden2 = "-->";
    8. }
    9. ?>
    А html-шаблон теперь имеет вид
    Код (Text):
    1. ...html ...
    2. {hidden1}
    3. html (элемент формы, например)
    4. {hidden2}
    5. ... html ...
    Все работает, но может по незнанию и неумению намудрил че-нить ?
     
  20. Vitas

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

    С нами с:
    7 фев 2006
    Сообщения:
    595
    Симпатии:
    0
    Адрес:
    Новосибирск, Академгородок
    Лучше сделать поддержку блоков а-ля PEAR HTML_Template_IT и т.п.
     
  21. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    как я уже говорил, потоков вывода (буферов) может быть много и в этом вся прелесть.

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

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

    понятно?
     
  22. Border

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

    С нами с:
    22 авг 2006
    Сообщения:
    41
    Симпатии:
    0
    Не совсем.
    Как я понимаю, задача №1 - отделить код от дизайна, задача №2 - сделать количество элементов дизайна минимальным (необходимым и достаточным). В зависимости от каких-либо параметров подхватываем или формируем "на лету" составляющие в разные буферы, вставляем обработанные в коде данные и при выводе собираем.
    Соответственно, если у меня есть "большая" форма, один из элементов которой, должен появляться по условию, то мне придется разбивать форму на три куска: до условного элемента, условный элемент, после условного элемента. Т.е. получается, что количество элементов дизайна (шаблонов) увеличивается.
    Я так по кусочкам и собираю. Один из кусочков у меня как раз форма и есть, только не всегда должны появляться все поля.
    Либо я не улавливаю мысль, которую Вы пытаетесь донести :oops:
    Если не сложно, объясните "на пальцах".

    ЗЫ. Переделываю сайт не из-за необходимости, просто хочется разобраться в PHP и писать хотя бы в первом приближении правильно. Сорри за возможно ламерские вопросы .. но вроде бы раздел для новичков :)
     
  23. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    Border

    когда собирается форма (логика представления) тогда и надо в буфер записывать то, что покажется, а в основном шаблоне будет просто поле {FORMA} куда потом вывод из буфера запишется.


    $FORM = new Buffer();
    $FORM->Send();
    if(...) { $FORM->Send();

    $BODY = new Buffer();
    $BODY->LoadFromFile();
    $TPL['FORMA'] = $FORM->Read();
    $BODY->Parse($TPL);
    $BODY->Show();
     
  24. Border

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

    С нами с:
    22 авг 2006
    Сообщения:
    41
    Симпатии:
    0
    440hz
    Можно для тех, кто в танке ...
    Есть помимо всего прочего форма, которую нужно вывести после нажатия кнопки "Submit"
    Код (Text):
    1. <form name = "test" action="index.php" method="post">
    2. Name <input type="text" name="Name" value="{Name}"><br>
    3. Select <select name="Select">
    4. <option selected> {Select} </option>
    5. <option> One </option> 
    6. <option> Two </option>
    7. <option> Three </option>
    8. </select><br>
    9. Something <input type="text" name="Something" value="{Something}"><br>
    10. <input name="Submit" type="submit" value="Done">
    11. </form>
    Нужно вывод делать по условию
    PHP:
    1. <?
    2. if ($_POST["Select"] !== "Two") {
    3.     // не выводим в форме поле Something
    4. }
    5. ...
    6. ?>
     
  25. Keo

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

    С нами с:
    20 сен 2006
    Сообщения:
    38
    Симпатии:
    0
    Объясните пожалуйста если не сложно, каким образом парсер отрабатывает {now} в $now и {title} в $title....

    Никак не пойму...