<MyRusakov.ru />

Создание Интернет-магазина на PHP и MySQL

Создание Интернет-магазина на PHP и MySQL

Видеокурс "Создание Интернет-магазина на PHP и MySQL" - это уникальный курс по созданию Интернет-магазина с нуля. Особенностью данного курса является то, что создание идёт с самого начала, то есть от идеи. Далее создаётся дизайн всех необходимых страниц, после делается их вёрстка. Затем создаётся движок на PHP и MySQL, после делается Admin-панель и, наконец, готовый сайт размещается в Интернете.

Адрес созданного в этом курсе сайта: http://storedvd.ru

Всё создание сайта будет происходить на Ваших глазах, поэтому Вы легко сможете повторить весь процесс создания сложного функционального сайта уже при разработке своего портала.

Подробнее
Подписка

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Каким движком Вы предпочитаете пользоваться?

Шаблонизатор на PHP

Шаблонизатор на PHP

Меня многократно просили дать код шаблонизатора на PHP, которым я пользуюсь. Но прежде чем перейти к этому коду, давайте немного расскажу о наиболее популярном шаблонизаторе - Smarty. Сразу скажу, что я всегда был против всех этих чужих и огромных библиотек. Но Smarty я стерпел и некоторое время использовал, а потом я подумал: "А зачем мне нужна эта помойка, если от шаблонизатора мне нужен минимум функциональности?".

Действительно, а что вообще нужно от шаблонизатора? От него нужно лишь подставлять в нужные места tpl-файлов определённые переменные из PHP. Все говорят, что PHP-код в tpl-файлах - это плохо. А чем лучше Smarty-код в tpl-файлах? Да абсолютно ничем, и это даже хуже, поскольку этот Smarty-код потом преобразуется в PHP-код и выполняется.

Smarty уже так сильно разошёлся, что стал вообще отдельным языком со своим синтаксисом, со своими циклами и условиями. Разве это требуется от шаблонизатора?

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

Итак, привожу код своего шаблонизатора, которым я настоятельно рекомендую Вам пользоваться:

<?php
class Template {

  private $dir_tmpl; // Директория с tpl-файлами
  private $data = array(); // Данные для вывода

  public function __construct($dir_tmpl) {
    $this->dir_tmpl = $dir_tmpl;
  }

  /* Метод для добавления новых значений в данные для вывода */
  public function set($name, $value) {
    $this->data[$name] = $value;
  }

  /* Метод для удаления значений из данных для вывода */
  public function delete($name) {
    unset($this->data[$name]);
  }

  /* При обращении, например, к $this->title будет выводиться $this->data["title"] */
  public function __get($name) {
    if (isset($this->data[$name])) return $this->data[$name];
    return "";
  }

  /* Вывод tpl-файла, в который подставляются все данные для вывода */
  public function display($template) {
    $template = $this->dir_tmpl.$template.".tpl";
    ob_start();
    include ($template);
    echo ob_get_clean();
  }
}

?>

Всего 1 файл размером 0.5 КБ, вместо больше 100 файлов и примерно 1 МБ2000 раз больше). Но при этом всё самое важное данный класс сделает.

Теперь создадим tpl-файл (пусть называется menu.tpl), который будет без проблем обработан этим шаблонизатором:

<ul>
  <?php foreach ($this->menu as $link => $name) { ?>
    <li>
      <a href="<?=$link?>"><?=$name?></a>
    </li>
  <?php } ?>
</ul>

И, наконец, давайте напишем PHP-файл, который будет вызывать шаблонизатор:

<?php
  $template = new Template("tmpl/");
  $menu = array();
  $menu["http://site.ru"] = "Главная";
  $menu["http://site.ru/page-1.html"] = "Страница 1";
  $menu["http://site.ru/page-2.html"] = "Страница 2";
  $template->set("menu", $menu);
  $template->display("menu");
?>

Если бы мы использовали Smarty, то у нас было бы всё ровно так же, но в tpl-файле мы бы написали код Smarty, который потом бы заменялся на PHP и выполнялся. А мы же сразу написали этот PHP-код. И какой смысл учить отдельный язык, который будет лишь тормозить работу, а также требует наличие огромной библиотеки?

Надеюсь, данная статья Вам покажет, что не нужно гнаться за бессмысленной функциональностью Smarty. Всё это в гораздо большем объёме есть в PHP, а задача шаблонизатора всего лишь одна - подставлять в tpl-файлы значения, полученные из PHP. Всё.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (71):

sync.o sync.o 20.02.2013 10:32:18

Там в цикле foreach ($this->menu as $name => $link) ключ и значение поменять местами нужно)

Ответить

Admin Admin 20.02.2013 22:42:37

Спасибо, подправил!

Ответить

nevek nevek 13.04.2014 09:08:42

Не получается передать переменную из .php в .tpl файл. Обращался в вашу тех поддержку (давно уже) сказали подождать - все еще жду. Может объясните как это сделать и можно ли обойтись без массива ?

Ответить

alexandrdante alexandrdante 13.04.2014 19:43:12

Задайте свой вопрос снова в службу поддержки Возможно он затерялся

Ответить

Silver78 Silver78 21.02.2013 02:58:48

А для чего вообще этот шаблонизатор? Можно чуточку поподробнее об этом для чайников? :)

Ответить

Admin Admin 21.02.2013 09:52:16

Для движков он нужен, чтобы не смешивать лишний раз HTML и PHP.

Ответить

greatt169 greatt169 21.02.2013 13:06:33

Очень полезная штука. С помощью такой технологии вполне можно создать собственную cms, не чем не уступающую ныне известным, но она будет намного быстрее, намного меньше весить, к тому же вы сможете реализовать лишь те функции, которые вам нужны и сделать абсолютно любой уникальный дизайн. Спасибо Михаил за вашу помощь!

Ответить

malina95 malina95 24.02.2013 23:58:22

А как сделать чтобы автоматом если есть в файле базовые переменные, например {address} заменялись на переменные из конфиг файла?

Ответить

Admin Admin 25.02.2013 10:13:18

В конструкторе Template сразу через метод set() добавить все эти всегда присутствующие конструкции.

Ответить

malina95 malina95 25.02.2013 22:07:42

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

Ответить

Admin Admin 26.02.2013 09:38:00

Метод set фактически и подготавливает набор данных для будущей подстановки в шаблоне.

Ответить

malina95 malina95 27.02.2013 22:53:27

Ваш класс конечно хороший, но мне кажется что этот немного лучше http://malinichev.ru/lesson/php-html-template.html как вы считаете?

Ответить

malina95 malina95 08.03.2013 00:39:06

Михаил, я всё таки решил испробовать ваш класс в деле, и попал на неожиданную проблему, как мне выводить переменные в шаблоне, если массив у меня двухмерный, при выводе вашего массива menu выходит нечнто такое: Array ( [http://site.ru] => Главная [http://site.ru/page-1.html] => Страница 1 [http://site.ru/page-2.html] => Страница 2 ), а при выводе моего массива выходит такое: Array ( [0] => Array ( [id] => 1 [username] => Владислав Малиничев ) ) Как поступить в такой ситуации, шаблонизатор использую в паре с вашим классом для бд.

Ответить

malina95 malina95 08.03.2013 01:08:16

Всё разобрался, даже когда цикл по логике не нужен, через него всё равно нужно прогонять в шаблоне... Вы бы это сразу объяснили, а то голову ломал 4 часа. Ну вы сами подумайте, зачем нужен цикл, когда я вывожу только данные одной таблицы где поле равно числу, там ведь не нужен цикл, я прав? Или это у меня уже мозги плывут в нехорошую сторону?

Ответить

Admin Admin 08.03.2013 10:31:33

Для вывода массива нужен цикл, по-другому не бывает.

Ответить

malina95 malina95 08.03.2013 14:52:51

Теперь буду знать

Ответить

F o x Y F o x Y 15.03.2013 14:26:15

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

Ответить

malina95 malina95 24.03.2013 05:37:03

Я бы тоже хотел услышать... Даже если взять пример блока только для авторизованных, вот как его сделать?

Ответить

Admin Admin 24.03.2013 10:46:12

Через if в tpl-файле. И если авторизован, то вывести, иначе нет.

Ответить

vegas vegas 14.04.2013 07:37:13

Подскажите, пжлста, у Вас в menu.tpl <?=$link?> и <?=$name?> - это синтаксис такой, или указатели для str_replace()? Просто еще не сталкивался с таким выражением

Ответить

Admin Admin 14.04.2013 11:48:01

<?=$link?> аналогично записи <?php echo $link;?>, просто первый вариант короче.

Ответить

vegas vegas 14.04.2013 14:06:07

Вот оно что! Там еще short_open_tag надо было включить, поэтому у меня и не получалось. Спасибо!

Ответить

tytar tytar 17.04.2013 14:22:15

Простите, но это такого как раз и был введен альтернативный синтаксис <ul> <?php foreach ($this->menu as $link => $name) { ?> <li> <a href="<?=$link?>"><?=$name?></a> </li> <?php } ?> </ul> if ($a == 5): echo "a равно 5"; echo "..."; elseif ($a == 6): echo "a равно 6"; echo "!!!"; else: echo "a не равно ни 5 ни 6"; endif;

Ответить

malina95 malina95 08.05.2013 18:33:34

Ещё бы класс для валидации всех данных с GET и POST и был бы полный набор...

Ответить

emulexx emulexx 14.05.2013 12:15:35

Здравствуйте, Михаил! Подскажите пожалуйста, как с помощью Вашего шаблонизатора вывести многоуровневое горизонтальное меню из базы данных. --Структура таблицы `menu` CREATE TABLE IF NOT EXISTS `menu` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `parent_id` int(11) DEFAULT NULL, `title` varchar(255) DEFAULT NULL, `link` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; Буду очень признателен за помощь!

Ответить

Admin Admin 14.05.2013 13:31:51

Многоуровневое меню делается с помощью множества ul, внутри которых вложены другие ul. Нужно создать отдельный tpl-файл для одноуровневого меню, а внутри цикла в этом файле сделать подключение этого же файла, если требуется создать новый уровень, если не требуется, то просто вывести пункт меню. Таким образом, будет своего рода рекурсия, только тут не функция вызывается, а файл выводится. В основе это, но, конечно, придётся ещё поработать здесь над алгоритмом и над видом данных с меню.

Ответить

Dima Dima 23.06.2013 15:29:38

Я так понимаю в подобных шаблонизаторах нельзя использовать циклы и if,else? Чтоб вывести в цикле,то сам цикл помещаем в пхп в переменную, а потом уже выводим,эта переменная потом выглядит допустим так $content='цикл' , а потом $content заменяем на {content} или <?=$content?> в шаблоне? Т.е. частично html всеравно будет присутствовать в файле обработчике? По другому только smarty и т.п. или дорабатывать этот шаблонизатор?

Ответить

Admin Admin 23.06.2013 21:30:31

Здесь как раз и можно использовать if и циклы. <?php if () { ?>тут html-код<?php } ?>

Ответить

Dima Dima 24.06.2013 08:28:26

А как вызвать файл шаблона.Допустим у меня папка template,в ней фаил header.tpl У вас я так понимаю вызов тут $template = new Template("tmpl/"); я указал путь $template = new Template("template/header.tpl"); но так не работает

Ответить

Dima Dima 24.06.2013 08:59:05

И что за переменная $link в этом коде <?php foreach ($this->menu as $link => $name) { ?> ? в ней я так понял содержится эта часть ["http://site.ru"],а как быть если у меня несколько переменных? ....О вроде с директориями разобрался,и в цикле вывелось что нужно,но не до конца,данные из бд не вывелись,я так понимаю переменные пустые

Ответить

Dima Dima 24.06.2013 11:54:05

Можете подсказать что не так,почему не выводятся данные вот пхп $template = new Template("template/"); $top = array(); $top['/'.$categoryUrl.'/'.$myrow77['url']] = $url; $top[$myrow['title']] = $title; $template->set("header", $top); $template->display("header"); а вот header.tpl <?php foreach ($this->header as $top => $name) { ?> <li> <div class="top-text"><a href="<?=$url?>"><?=$title?></a></div></li> <?php } ?> Но все переменные пустые,не могу понять в чем причина.

Ответить

Admin Admin 24.06.2013 19:01:47

http://myrusakov.ru/php-finderror.html

Ответить

Admin Admin 24.06.2013 19:01:15

Файл шаблона надо подключить через <?php require_once "header.tpl"; ?> - и это непосредственно в main.tpl

Ответить

Dima Dima 25.06.2013 02:09:07

Да причем тут поиск ошибок.У вас в примере простейший пример foreach ($this->menu as $link => $name) Получается в цикле используется только одна переменная,а как мне вывести к примеру 4 переменных? У меня допустим есть переменные $img,$title,$url,$text. Как их вывести через цикл foreach? При этом в цикле переменные могут использоваться по несколько раз.

Ответить

Admin Admin 25.06.2013 10:39:32

Так и выводите: <?=$title?> И не важно где, хоть в цикле, хоть нет.

Ответить

Dima Dima 25.06.2013 11:13:27

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

Ответить

Astar Astar 25.07.2013 22:29:51

Есть такой вопрос тогда) Есть допустим шаблон с именем index.tpl, а мне необходимо в этот шаблон вставить еще один - например шаблон с формой регистрации registration_form.tpl Как мне тогда поступить используя ваш шаблонизатор? Заранее спасибо!

Ответить

Admin Admin 26.07.2013 19:29:00

Сначала собираете целый шаблон, затем заменяете значения шаблонизатором.

Ответить

Astar Astar 28.07.2013 01:10:32

А что если файл registration_form.tpl прочитать в строку и записать ее в переменную, а затем эту переменную присоединить к выводимой информации в нужном месте?

Ответить

Admin Admin 28.07.2013 23:39:49

Можно и так.

Ответить

sapr sapr 02.08.2013 02:29:29

Объясните пожалуйста чем данный подход хуже ----- php-файл------ <?php $menu = array(); $menu["http://site.ru"] = "Главная"; include "menu.tpl"; ?> ----- файл menu.tpl------ <ul> <?php foreach ($menu as $link => $name) { ?> <li> <a href="<?=$link?>"><?=$name?></a> </li> <?php } ?> </ul> ---------------- заранее спасибо

Ответить

Admin Admin 02.08.2013 16:00:28

В такой структуре проще запутаться, если у Вас много всего выводится.

Ответить

parmactep parmactep 15.09.2013 08:28:21

Не поленился зарегистрироватся чтобы поинтересоватся, зачем вы вывод буферизируете?

Ответить

Fantik Fantik 03.10.2013 13:52:06

Решился Ваш шаблонизатор у себя использовать для организации вывода разных версий сайта, но так как и у многих других здесь возникли проблемы. Не могу понять как выводить переменные в шаблон. Допустим таким образом в php файле: $index = array('time' => $time); $tpl->set('index', $index); $tpl->display('index'); а в tpl получается выводится только таким образом: $this->index['time'] Это через чур много, можно как-то покороче? Таким образом <?=$time?> не работает

Ответить

Admin Admin 03.10.2013 15:08:19

В старых версиях PHP так и было, а в новых только через $this.

Ответить

Fantik Fantik 03.10.2013 17:08:41

Спасибо за ответ, жаль что так, а исправить это если только дополнительную функцию дописать для замены? или ещё какие-либо варианты возможны?

Ответить

Admin Admin 03.10.2013 21:19:36

Только лишь вначале tpl файла сделать из переменных класса обычные локальные переменные, перебрав через цикл всё, что передано в шаблон.

Ответить

Fantik Fantik 03.10.2013 21:45:34

Еще раз спасибо, думаю это уже будет излишняя и не обоснованная операция. Пока оставлю как есть

Ответить

@Alex@ @Alex@ 10.10.2013 15:57:45

Как можно очистить значения? Пробывал unset,не помогает,вроде в вашем классе есть функция для удаления значений. Но с ней тоже ничего не получилось, ну или я не так что то делал. Вообщем получается следующее, допустим вывожу картинку $template->set('img', ''.$row['img'].''); В шаблоне <?=$this->img?>, либо <?=$this->data['img']?>, без разницы(но первый варинт удобней,он короче). Вообщем больше одного раза я не могу использовать метку 'img'. Если я ее проставлю к примеру дважды в разных местах шаблона то тогда выведется одна и таже картинка. Чтоб все выводилось как нужно,надо в др. месте например делать метку img2 , $template->set('img2', ''.$row['img'].'');....Ну и так со всеми метками. В итоге у меня в шаблонах куча этих разных меток и как то неудобно получается, да и не красиво. С циклами тоже самое <?php foreach ($this->menu as $value){ ?> Далее <?=$value['url']?> и т.д. ,но тут попроще нужно только чтоб $this->menu было разное т.е. $this->menu2, $this->menu3 и .т.п. Думаю понтяно обьяснил? Сори если что то непонятно. Вообщем можно как то сделать чтоб можно было использовать одни и теже метки в шаблонах, а не присваивать постоянно разные имена?

Ответить

@Alex@ @Alex@ 10.10.2013 16:18:18

О что то получилось,только не так как хотел. Загнал в массив потом через foreach прогнал,и в шаблоне можно использовать <?=$this->info[img]?>. Хотя б так,правда метку info можно использовать только один раз. Но все же так по лучше будет.

Ответить

ссс ссс 14.11.2013 15:34:12

ob_start(); include ($template); echo ob_get_clean(); Посему не просто include ($template); ?

Ответить

Admin Admin 14.11.2013 21:13:39

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

Ответить

ссс ссс 15.11.2013 12:23:03

В том то и дело, что строка echo ob_get_clean(); ВЫВЕДЕТ буфер после чего ОЧИСТИТ его. Тогда какой смысл в этой буферизации, ведь если вдруг потребуется вернуть шаблон с осуществленной подстановкой, то только внеся изменения в сам метод display. Или я что-то не так понял?

Ответить

Admin Admin 15.11.2013 19:58:29

Если добавить параметр $ret (по умолчанию, можно сделать false) в метод, то тогда можно делать так: if ($ret) return ob_get_clean(); else echo ob_get_clean();

Ответить

zirex zirex 28.01.2014 01:33:43

А если, предположим мне нужно вывести имя пользователя, причем не используя php код в шаблоне,а используя метку {user}. Мои действие следующие: в функции public function display($template)я пишу foreach($this->data as $key => $value) { $this->template = str_replace($key, $value, $this->template); } echo $this->template; А потом в index.php $template->set('{name}', 'Sergey'); По логике так или нет? Просто я так попробовал, у меня ничего не вышло. Хотелось бы узнать решение.

Ответить

tikkiwiki tikkiwiki 31.01.2014 10:54:37

Покажите код.

Ответить

CoMMoN CoMMoN 10.02.2014 11:19:06

А что делать если у тебя в пхп коде есть такие методы while(), case, swich() и тд, как быть в этом случае с вашим шаблонизатором?

Ответить

tikkiwiki tikkiwiki 12.02.2014 12:15:18

Не понял если честно, в чем проблема?

Ответить

shamil shamil 30.08.2014 06:42:28

подскажите пожалуста ,как выводить результат данного кода на странице

Ответить

shamil shamil 30.08.2014 10:36:52

какой код выводить?

Ответить

shamil shamil 30.08.2014 10:41:35

я сайт с урока ООП русакова скопипастип,а толку нету,обратно перешел на упрощенный режим,с этого примера попробую внедрить ООП

Ответить

yurecnt yurecnt 08.12.2014 12:34:19

Оно конечно проще и эстетичней... чем смарти, а как же замечательная фишка - кеширование? То есть в любом случае данный код будет обрабатываться, а не брать уже готовый файл на отдачу из кэша. При чем, я в смарти настроил кеширование и компилирование шаблонов в ram-диск, благодаря чему - скорость вывода данных значительно возрасла! Вот рецепт http://yurecnt.ru/Pro_Smarty_-_zastavlyaem_sayt_letat_esche_byistree_.html

Ответить

Tarik Tarik 19.01.2015 22:04:12

можливо для виводу потрібно усі параметри прогнати через extract() у буфері, в мене усе працює, ось: public function display($template) { $template = $this->dir_tmpl.$template.".tpl"; ob_start(); extract($this->data); include ($template); echo ob_get_clean(); }

Ответить

idkvik idkvik 21.05.2015 10:13:35

В функции display($template) используется вызов ob_start(); что это и откуда???

Ответить

Drogon Drogon 24.05.2015 00:01:16

http://php.net/manual/ru/function.ob-start.php почитайте тут.

Ответить

Tanya82 Tanya82 14.10.2015 20:23:30

В класс наверное стоит добавить еще один метод? /*для осуществления проверок типа isset($this->title) */ public function __isset($name) { if (isset($this->data[$name])) return $this->data[$name]; return ""; } тк в шаблоне не срабатывает isset($this->....)

Ответить

beshot beshot 21.10.2015 18:53:59

А как, в приведенном классе, сделать автоматический искейпинг данных. То есть, чтобы на выводимую переменную автоматически накатывалась htmlspecialchars?

Ответить

logaut logaut 03.12.2015 14:30:58

Здравствуйте, Михаил! Решил спросить на счёт шаблонизатора. Я не совсем понял, зачем здесь вот эти методы: /* Метод для добавления новых значений в данные для вывода */ public function set($name, $value) { $this->data[$name] = $value; } /* Метод для удаления значений из данных для вывода */ public function delete($name) { unset($this->data[$name]); } И ещё. В вашем шаблонизаторе показан пример где в html коде подставляются переменные, а не вот эти элементы: <ul> <?php foreach ($this->menu as $link => $name) { ?> <li> <a href="{link}">{name}</a> </li> <?php } ?> </ul> Как нужно изменить шаблонизатор, чтобы подставлялись только элементы: {name}, например?

Ответить

Alex_daev Alex_daev 03.03.2016 19:35:42

уже 8 дней занимаюсь над созданием своего движка. Нет денег чтобы купить платные курсы. А бесплатные вот такие вот... то есть я с вами полностю согласен

Ответить

Alex_daev Alex_daev 03.03.2016 19:37:17

из бесплатных где все "нормально" описано?

Ответить

logaut logaut 04.03.2016 12:53:29

Alex_daev, а вы почитайте эту статью: http://myrusakov.ru/php-use-tpl.html Кстати, я этот пример пробовал на практике и мне очень понравилось, настолько всё просто. И ещё... За 8 дней вряд ли вы создадите свой движок.

Ответить

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.