<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<link>http://webew.ru/</link>
<language>ru</language>
<title>Webew.ru: теория и практика веб-технологий</title>
<pubDate>Fri, 27 Feb 2026 15:03:52 +0300</pubDate>
<description>Новые статьи по Javascript, AJAX, HTML, CSS, PHP, MySQL, С/С++, поисковому продвижению сайтов и системам управления содержимым.</description>
<image>
<url>http://webew.ru/i/webew_rss.gif</url>
<title>Webew.ru: теория и практика веб-технологий</title>
<link>http://webew.ru/</link>
</image>
<item>
  <title>Псевдо-checkbox на чистом CSS без фоновых изображений</title>
  <link>http://webew.ru/articles/5806.webew</link>
  <guid>http://webew.ru/articles/5806.webew</guid>
  <pubDate>Sat, 24 Jun 2017 16:41:54 +0300</pubDate>
  <description>&lt;p&gt;
	Как сделать красивый стилизованный чекбокс и при этом не написать ни строчки javascript и не искать иконки.
&lt;/p&gt;
&lt;script&gt; var CONTENTS_LEVEL = 2; &lt;/script&gt;
&lt;div class=&quot;example&quot; id=&quot;example-1&quot;&gt;
	&lt;label&gt;
		&lt;input type=&quot;checkbox&quot; class=&quot;usual&quot;&gt;
		это обычный чекбокс
	&lt;/label&gt;
	&lt;label&gt;
		&lt;input type=&quot;checkbox&quot;&gt;
		&lt;span class=&quot;pseudocheckbox&quot;&gt;а это - стилизованный&lt;/span&gt;
	&lt;/label&gt;
	&lt;style&gt;
		#example-1 .pseudocheckbox::before {
			content: &quot;\00A0&quot;;
			display: inline-block;
			box-sizing: border-box;
			width: 20px;
			height: 20px;
			background-color: white;
			border: 2px solid #B0B0B0;
			border-radius: 2px;
			margin-right: 6px;
			vertical-align: baseline;
			text-align: center;
			font-family: Arial, sans-serif;
			font-size: 16px;
			line-height: 16px;
			font-weight: bold;
			color: #808080;
			}
		#example-1 input[type=checkbox]:checked + .pseudocheckbox::before { content: &quot;\2713&quot;; }
		/* для статьи */
		#example-1 &gt; label:first-child { margin-right: 2em; }
		#example-1 input[type=checkbox] { display: none; }
		#example-1 label { display: inline-block; }
		#example-1 input[type=checkbox].usual { display: inline-block; width: auto; vertical-align: middle; }
	&lt;/style&gt;
&lt;/div&gt;
&lt;p&gt;
	Вот как выглядит код стилизованного чекбокса:
&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;label&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;pseudocheckbox&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;а это - стилизованный&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;input&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;type=checkbox&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;display&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;none&lt;/span&gt;; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re1&quot;&gt;.pseudocheckbox&lt;/span&gt;:&lt;span class=&quot;re2&quot;&gt;:before&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es0&quot;&gt;\0&lt;/span&gt;0A0&amp;quot;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;display&lt;/span&gt;: inline-&lt;span class=&quot;kw2&quot;&gt;block&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; box-sizing: border-box;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;width&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;20px&lt;/span&gt;; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;height&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;20px&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;background-color&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;white&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;border&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;solid&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;#B0B0B0&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; border-radius: &lt;span class=&quot;re3&quot;&gt;2px&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;margin-right&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;6px&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;vertical-align&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;baseline&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;text-align&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;center&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;font-family&lt;/span&gt;: Arial, &lt;span class=&quot;kw2&quot;&gt;sans-serif&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;font-size&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;16px&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;line-height&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;16px&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;font-weight&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;bold&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;color&lt;/span&gt;: &lt;span class=&quot;re0&quot;&gt;#&lt;span class=&quot;nu0&quot;&gt;808080&lt;/span&gt;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
input&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;type=checkbox&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;re2&quot;&gt;:checked&lt;/span&gt; + &lt;span class=&quot;re1&quot;&gt;.pseudocheckbox&lt;/span&gt;:&lt;span class=&quot;re2&quot;&gt;:before&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es0&quot;&gt;\2&lt;/span&gt;713&amp;quot;&lt;/span&gt;; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
	Разберем этот код подробно.
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;label&quot;&gt;&lt;/a&gt;Задействуем &amp;lt;label&amp;gt;&lt;/h2&gt;
&lt;p&gt;
	Для начала нужно скрыть сам чекбокс:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;input&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;type=checkbox&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;display&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;none&lt;/span&gt;; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
	Его и относящийся к нему текст нужно заключить в &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;label&lt;/span&gt;, чтобы клик мыши по тексту приводил к изменению состояния чекбокса:
&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;label&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;pseudocheckbox&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;а это - стилизованный&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
	Мы, однако, не только поместили текст внутрь &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;label&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, но и обернули его в &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;span&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. Для чего же это нужно?
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;adjacent-sibling&quot;&gt;&lt;/a&gt;Селектор соседа и псевдокласс :checked&lt;/h2&gt;
&lt;p&gt;
	В CSS есть &lt;a href=&quot;https://www.w3.org/TR/css3-selectors/#adjacent-sibling-combinators&quot;&gt;селектор соседа&lt;/a&gt;. Он позволяет применить стили к указанному элементу только в том случае, если прямо перед ним есть некоторый другой элемент. Записывается он с помощью символа &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;+&lt;/span&gt; и выглядит, например, вот так:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;input&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;type=checkbox&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; + span &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;правила&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
	Вышеуказанная запись означает: применить правила ко всем &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&amp;lt;span&amp;gt;&lt;/span&gt;, перед которыми есть &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&amp;lt;input type=&lt;span class=&quot;st0&quot;&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
	С помощью подобного выражения можно провернуть одну хитрость: ограничить предшествующие элементы только теми чекбоксами, которые «включены». Это нам позволит сделать псевдокласс &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re2&quot;&gt;:checked&lt;/span&gt;&lt;/span&gt;:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;input&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;type=checkbox&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;re2&quot;&gt;:checked&lt;/span&gt; + span &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;правила&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
	Такая запись позволяет визуально выделить конкретно те &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&amp;lt;span&amp;gt;&lt;/span&gt;, которые следуют за включенными чекбоксами. Эффект от такого выделения иллюстрирует простейший пример:
&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;label&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;span&amp;gt;&lt;/span&gt;&lt;/span&gt;щелкни по мне&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;input&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;type=checkbox&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;re2&quot;&gt;:checked&lt;/span&gt; + span &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;font-weight&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;bold&lt;/span&gt;; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
	Вот как получится:
&lt;/p&gt;
&lt;div class=&quot;example&quot; id=&quot;example-2&quot;&gt;
	&lt;label&gt;
		&lt;input type=&quot;checkbox&quot;&gt;
		&lt;span&gt;щелкни по мне&lt;/span&gt;
	&lt;/label&gt;
	&lt;style&gt;
		#example-2 input[type=checkbox] { width: auto; }
		#example-2 input[type=checkbox]:checked + span { font-weight: bold; }
	&lt;/style&gt;
&lt;/div&gt;
&lt;p&gt;
	(Заметим, что &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&amp;lt;span&amp;gt;&lt;/span&gt; вместе с &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&amp;lt;input type=checkbox&amp;gt;&lt;/span&gt; находится внутри &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&amp;lt;label&amp;gt;&lt;/span&gt;, поэтому клик по нему приводит к изменению состояния &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&amp;lt;input&amp;gt;&lt;/span&gt;.)
&lt;/p&gt;
&lt;p&gt;
	Селектор в исходном примере выглядит немного по-другому: не&lt;br&gt;
	&lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;input&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;type=checkbox&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;re2&quot;&gt;:checked&lt;/span&gt; + span&lt;/span&gt;, а&lt;br&gt; &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;input&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;type=checkbox&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;re2&quot;&gt;:checked&lt;/span&gt; + &lt;span class=&quot;re1&quot;&gt;.pseudocheckbox&lt;/span&gt;&lt;/span&gt;. По такому селектору браузер быстрее найдет нужный элемент: ему легче искать среди элементов класса &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;pseudocheckbox&lt;/span&gt;, чем среди всех &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;span&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. Так что класс добавлен для повышения производительности и никакой другой смысловой нагрузки не несет.
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;before&quot;&gt;&lt;/a&gt;Стилизуем ::before&lt;/h2&gt;
&lt;p&gt;
	Вернемся к нашей задаче. Нам требуется не выделять сам &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&amp;lt;span&amp;gt;&lt;/span&gt;, а добиться, чтобы слева от него появилось нечто похожее на переключатель. Для этого нам поможет псевдоэлемент &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;:&lt;span class=&quot;re2&quot;&gt;:before&lt;/span&gt;&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
	&lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;:&lt;span class=&quot;re2&quot;&gt;:before&lt;/span&gt;&lt;/span&gt; — это способ дописать что-то в элемент непосредственно перед его содержимым средствами CSS.
&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/span&gt;раз&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/span&gt;два&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;div:&lt;span class=&quot;re2&quot;&gt;:before&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;st0&quot;&gt;&amp;quot;Это ::before &amp;quot;&lt;/span&gt;; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;example&quot; id=&quot;example-3&quot;&gt;
	&lt;div&gt;раз&lt;/div&gt;
	&lt;div&gt;два&lt;/div&gt;
	&lt;style&gt;
		#example-3 div::before { content: &quot;Это ::before &quot;; }
	&lt;/style&gt;
&lt;/div&gt;
&lt;p&gt;
	Современные браузеры позволяют стилизовать &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;:&lt;span class=&quot;re2&quot;&gt;:before&lt;/span&gt;&lt;/span&gt; так же, как это делается для обычных HTML-элементов: задавать размеры и отступы, добавлять границы, фон и т.д. Это позволит нам придать ему вид квадратика с рамкой, похожего на переключатель. Взглянем еще раз на правила для него и разберемся, для чего нужно каждое из них:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re1&quot;&gt;.pseudocheckbox&lt;/span&gt;:&lt;span class=&quot;re2&quot;&gt;:before&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &amp;nbsp;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es0&quot;&gt;\0&lt;/span&gt;0A0&amp;quot;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;display&lt;/span&gt;: inline-&lt;span class=&quot;kw2&quot;&gt;block&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; box-sizing: border-box;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;width&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;20px&lt;/span&gt;; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;height&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;20px&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;background-color&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;white&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;border&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;solid&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;#B0B0B0&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; border-radius: &lt;span class=&quot;re3&quot;&gt;2px&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;margin-right&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;6px&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;vertical-align&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;baseline&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;text-align&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;center&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;font-family&lt;/span&gt;: Arial, &lt;span class=&quot;kw2&quot;&gt;sans-serif&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;font-size&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;16px&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;line-height&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;16px&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;font-weight&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;bold&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;color&lt;/span&gt;: &lt;span class=&quot;re0&quot;&gt;#&lt;span class=&quot;nu0&quot;&gt;808080&lt;/span&gt;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
	&lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;content&lt;/span&gt;&lt;/span&gt; — свойство, необходимое псевдоэлементу, чтобы он проявился. Достаточно даже пустой строки. Но мы используем неразрывный пробел (об этом будет рассказано ниже). Его шестнадцатеричный код — &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;00A0&lt;/span&gt;:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es0&quot;&gt;\0&lt;/span&gt;0A0&amp;quot;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
	Нужно задать нашему «квадратику» ширину и высоту. Чтобы они подействовали, необходимо также указать &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;display&lt;/span&gt;: inline-&lt;span class=&quot;kw2&quot;&gt;block&lt;/span&gt;;&lt;/span&gt; (по умолчанию у &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;:&lt;span class=&quot;re2&quot;&gt;:before&lt;/span&gt;&lt;/span&gt; — &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;inline&lt;/span&gt;&lt;/span&gt;):
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;display&lt;/span&gt;: inline-&lt;span class=&quot;kw2&quot;&gt;block&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;width&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;20px&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;height&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;20px&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
	Удобней, чтобы ширина и высота рассчитывались с учетом толщины границ:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;box-sizing: border-box;&lt;/div&gt;
&lt;p&gt;
	Которые тут же и укажем вместе с закруглениями для красоты:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;border&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;solid&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;#B0B0B0&lt;/span&gt;;&lt;br /&gt;
border-radius: &lt;span class=&quot;re3&quot;&gt;2px&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
	И добавим небольшой отступ от текста:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;margin-right&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;6px&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
	Следует также обратить внимание на выравнивание самого «квадратика» относительно соседнего текста. Одним из подходящих вариантов является выравнивание по базовой линии текста:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;vertical-align&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;baseline&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
	В случае самого «квадратика» текстом является неразрывный пробел. Если бы текста внутри не было (&lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;st0&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;/span&gt;), такое выравнивание не подействовало бы. Вот почему в &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;content&lt;/span&gt;&lt;/span&gt; именно неразрывный пробел, а не пустая строка: выглядят они одинаково, а действуют в данном случае по-разному.
&lt;/p&gt;
&lt;p&gt;
	Остальные свойства относятся к переключателю в состоянии «включено».
&lt;/p&gt;
&lt;h2&gt;Состояние «включено» и Unicode-символ «галочка»&lt;/h2&gt;
&lt;p&gt;
	Отмеченный переключатель, очевидно, имеет некоторые отличия. Для нас это не проблема, потому что с помощью соседнего селектора можно обращаться не только к самому элементу, но и к его &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;:&lt;span class=&quot;re2&quot;&gt;:before&lt;/span&gt;&lt;/span&gt;:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;input&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;type=checkbox&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;re2&quot;&gt;:checked&lt;/span&gt; + &lt;span class=&quot;re1&quot;&gt;.pseudocheckbox&lt;/span&gt;:&lt;span class=&quot;re2&quot;&gt;:before&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; ... &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
	Отмеченный переключатель обычно имеет внутри «галочку». Здесь нам на помощь приходит  разнообразие символов Unicode, которое выходят далеко за пределы собственно букв и цифр. Есть среди этого многообразия и &lt;a href=&quot;https://ru.wikipedia.org/wiki/%D0%93%D0%B0%D0%BB%D0%BE%D1%87%D0%BA%D0%B0&quot;&gt;несколько значков для «галочки»&lt;/a&gt;. Код значка мы запишем в свойство &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;content&lt;/span&gt;&lt;/span&gt;:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;input&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;type=checkbox&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;re2&quot;&gt;:checked&lt;/span&gt; + &lt;span class=&quot;re1&quot;&gt;.pseudocheckbox&lt;/span&gt;:&lt;span class=&quot;re2&quot;&gt;:before&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es0&quot;&gt;\2&lt;/span&gt;714&amp;quot;&lt;/span&gt;; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
	В результате «галочка» будет вписана во все «квадратики» рядом с отмеченными чекбоксами, чего мы и добивалсь. Однако, не стоит забывать, что технически такая «галочка» — это обычный текстовый символ, который самостоятельно может и не выглядеть ровно так, как надо, и ему нужно ему в этом немного помочь.
&lt;/p&gt;
&lt;p&gt;
	Центрируем по горизонтали:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;text-align&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;center&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
	В разных шрифтах символ «галочки» может выглядеть немного по-разному, поэтому для ясности выбираем какой-то один и указываем его явно. Также подбираем размер:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;font-family&lt;/span&gt;: Arial, &lt;span class=&quot;kw2&quot;&gt;sans-serif&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;font-size&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;16px&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
	Кроме размера нужно добиться необходимого положения символа внутри квадратика по вертикальной оси. Лучше всего это делать с помощью &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;line-height&lt;/span&gt;&lt;/span&gt;:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;line-height&lt;/span&gt;: &lt;span class=&quot;re3&quot;&gt;16px&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
	 &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;line-height&lt;/span&gt;&lt;/span&gt; нужно подбирать индивидуально для каждого сочетания  размера и семейства шрифта.
&lt;/p&gt;
&lt;p&gt;
	При выравнивании по базовой линии текста (&lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;vertical-align&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;baseline&lt;/span&gt;&lt;/span&gt;) именно значение &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;line-height&lt;/span&gt;&lt;/span&gt; определеяет, где, собственно, будет нижняя граница текста у «квадратика». Если эти значения у отмеченного и неотмеченного будут отличаться, то они окажутся выровненными по-разному (так может получиться, например, если явно указать &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;line-height&lt;/span&gt;&lt;/span&gt; только у отмеченного). Поэтому &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;line-height&lt;/span&gt;&lt;/span&gt; лучше указывать в общем блоке стилей для &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;:&lt;span class=&quot;re2&quot;&gt;:before&lt;/span&gt;&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
	&lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;line-height&lt;/span&gt;&lt;/span&gt; обычно подбирают вместе с &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;font-size&lt;/span&gt;&lt;/span&gt;, поэтому его удобно иметь в блоке стилей рядом. &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;font-size&lt;/span&gt;&lt;/span&gt;, в свою очередь, может подбираться вместе с другими параметрами текста. Так что все их удобней перенести в общий блок для &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;:&lt;span class=&quot;re2&quot;&gt;:before&lt;/span&gt;&lt;/span&gt;, хотя, на первый взгляд, правила стилизации текста там выглядит нелогично, т.к. самого текста там нет.
&lt;/p&gt;
&lt;p&gt;
	Напоследок добавим жирность и укажем цвет:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;font-weight&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;bold&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;color&lt;/span&gt;: &lt;span class=&quot;re0&quot;&gt;#&lt;span class=&quot;nu0&quot;&gt;808080&lt;/span&gt;&lt;/span&gt;;&lt;/div&gt;</description>
</item>
<item>
  <title>Средства навигации по сайту: генерация с помощью PHP</title>
  <link>http://webew.ru/articles/5510.webew</link>
  <guid>http://webew.ru/articles/5510.webew</guid>
  <pubDate>Fri, 25 Dec 2015 15:31:19 +0300</pubDate>
  <description>&lt;!-- Средства навигации по сайту: генерация с помощью PHP --&gt;
&lt;script&gt;var CONTENTS_LEVEL = 2;&lt;/script&gt;
&lt;p&gt;
Вниманию читателей предлагается небольшая &lt;a name=&quot;download&quot; href=&quot;http://webew.ru/f/xR2K0knr.php&quot;&gt;библиотека функций&lt;/a&gt; для языка PHP, предназначенная, в основном, для создания интерфейсов навигации по спискам. Библиотека позволяет сделать необходимый PHP-код очень компактным.
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;sgp&quot;&gt;&lt;/a&gt;Замена значений GET-параметров в адресах&lt;/h2&gt;
&lt;p&gt;
Нередко бывает нужно получить URL, идентичный текущему, за исключением значения одного из GET-параметров.
&lt;/p&gt;
&lt;p&gt;
Распространенный пример — номер страницы списка:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;co2&quot;&gt;# Предположим, URL текущей страницы - http://site.ru/catalogue/?a=100&amp;amp;b=200&amp;amp;N=50&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co2&quot;&gt;# Пусть за номер страницы отвечает параметр 'p'.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;co2&quot;&gt;# Тогда чтобы получить URL для страницы № 2, нужен вот такой код:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$url&lt;/span&gt; = substitute_url_get_parameter&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co2&quot;&gt;# Функция вернет адрес, начиная со слэша (без доменного имени):&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;co2&quot;&gt;# /catalogue/?a=100&amp;amp;b=200&amp;amp;N=50&amp;amp;p=2&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Если в качестве значения GET-параметра функции передать &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;NULL&lt;/span&gt;&lt;/span&gt;, то он будет полностью исключен из адреса:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;co2&quot;&gt;# Предположим, мы на странице /catalogue/?a=100&amp;amp;b=200&amp;amp;N=50&amp;amp;p=2&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$url&lt;/span&gt; = substitute_url_get_parameter&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// вернет /catalogue/?a=100&amp;amp;b=200&amp;amp;N=50&amp;amp;p&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$url&lt;/span&gt; = substitute_url_get_parameter&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;, &lt;span class=&quot;kw2&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;co1&quot;&gt;// вернет /catalogue/?a=100&amp;amp;b=200&amp;amp;N=50&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
&lt;a name=&quot;sgp-multiple&quot;&gt;&lt;/a&gt;
Если в адресе нужно заменить сразу несколько параметров, это можно сделать за один вызов функции:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt; &lt;span class=&quot;co2&quot;&gt;# Для страницы /catalogue/?a=100&amp;amp;b=200&amp;amp;N=50&amp;amp;p=2&amp;amp;x=1&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$url&lt;/span&gt; = substitute_url_get_parameter&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'N'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;100&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw2&quot;&gt;NULL&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;br /&gt;
&lt;span class=&quot;co2&quot;&gt;# даст /catalogue/?a=100&amp;amp;b=200&amp;amp;N=100&amp;amp;x=1&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co2&quot;&gt;# Можно указывать единое значение для всех параметров (это удобно, если их нужно удалить)&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$url&lt;/span&gt; = substitute_url_get_parameter&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'N'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &amp;nbsp; &lt;span class=&quot;co2&quot;&gt;# даст /catalogue/?a=100&amp;amp;b=200&amp;amp;N&amp;amp;p&amp;amp;x=1&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$url&lt;/span&gt; = substitute_url_get_parameter&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'N'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;, &lt;span class=&quot;kw2&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;co2&quot;&gt;# даст /catalogue/?a=100&amp;amp;b=200&amp;amp;x=1&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
По умолчанию функция использует адрес текущей страницы (&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$_SERVER&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'REQUEST_URI'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/span&gt;). Если нужно использовать какой-то другой, его следует передать в качестве третьего аргумента:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$url&lt;/span&gt; = substitute_url_get_parameter&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$some_url&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;co2&quot;&gt;# Вызов вида substitute_url_get_parameter('p', 2)&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;co2&quot;&gt;# равносилен substitute_url_get_parameter('p', 2, $_SERVER['REQUEST_URI'])&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Есть &lt;a name=&quot;sgp-del&quot;&gt;&lt;/a&gt;&lt;em&gt;специальный режим работы функции, который позволяет удалить из адреса все GET-параметры, кроме указанных&lt;/em&gt;, которым, при желании, установить другие значения или же оставить их в неизменном виде:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$url&lt;/span&gt; = substitute_url_get_parameter&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'-'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'N'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'x'&lt;/span&gt;=&amp;gt;&lt;span class=&quot;nu0&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;co2&quot;&gt;# Для страницы http://site.ru/catalogue/?a=100&amp;amp;b=200&amp;amp;N=50&amp;amp;x=1&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;co2&quot;&gt;# &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; даст http://site.ru/catalogue/?N=50&amp;amp;x=3&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Как видно из примера, для работы в этом режиме первым аргументом функции нужно передать массив, первым элементом которого является строка &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'-'&lt;/span&gt;&lt;/span&gt;, а последующими — те переменные, которые следует оставить в адресе.
&lt;/p&gt;
&lt;p&gt;
Соответственно, вызов вида &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;substitute_url_get_parameter&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'-'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; позволяет получить адрес без GET-параметров.
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;pages&quot;&gt;&lt;/a&gt;&lt;!--Получение адресов для разбиения--&gt; Разбиение списка на страницы&lt;/h2&gt;
&lt;p&gt;
Типичная задача при работе со списком — получить перечень ссылок, соответствующих разным страницам этого списка. Номеру страницы при этом соответствует некоторый GET-параметр; в случае первой страницы он не задан и не должен присутствовать в ссылке на нее. Все остальные части адреса от страницы к странице должны сохраняться неизменными.
&lt;/p&gt;
&lt;p&gt;
Для решения такой задачи служит функция &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;nav_pages&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$pages&lt;/span&gt; = nav_pages&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// номер страницы - в $_GET[p]&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;nu0&quot;&gt;20&lt;/span&gt;, &amp;nbsp;&lt;span class=&quot;co1&quot;&gt;// сколько записей на одной странице &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$total_rows&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// суммарное число записей в разбиваемом на странице списке&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
В случае текущего адреса &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/catalogue/?a=100&amp;amp;b=200&amp;amp;p=3&lt;/span&gt; результат работы функции будет таким:
&lt;/p&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Array&lt;br /&gt;
(&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [list] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [1] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /catalogue/?a=100&amp;amp;b=200&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [num] =&amp;gt; 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [min] =&amp;gt; 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [max] =&amp;gt; 20&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [2] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /catalogue/?a=100&amp;amp;b=200&amp;amp;p=2&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [num] =&amp;gt; 2&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [min] =&amp;gt; 21&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [max] =&amp;gt; 40&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [3] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /catalogue/?a=100&amp;amp;b=200&amp;amp;p=3&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [num] =&amp;gt; 3&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [min] =&amp;gt; 41&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [max] =&amp;gt; 60&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [current] =&amp;gt; 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [4] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /catalogue/?a=100&amp;amp;b=200&amp;amp;p=4&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [num] =&amp;gt; 4&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [min] =&amp;gt; 61&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [max] =&amp;gt; 80&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [special] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [current] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /catalogue/?a=100&amp;amp;b=200&amp;amp;p=3&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [num] =&amp;gt; 3&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [min] =&amp;gt; 41&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [max] =&amp;gt; 60&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [prev] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /catalogue/?a=100&amp;amp;b=200&amp;amp;p=2&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [num] =&amp;gt; 2&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [min] =&amp;gt; 21&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [max] =&amp;gt; 40&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [next] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /catalogue/?a=100&amp;amp;b=200&amp;amp;p=4&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [num] =&amp;gt; 4&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [min] =&amp;gt; 61&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [max] =&amp;gt; 80&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
)&lt;/div&gt;
&lt;p&gt;
Ссылки &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;prev&lt;/span&gt; и &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;next&lt;/span&gt; присутствуют, если текущей не является первая или последняя страница соответственно. Ссылки &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;first&lt;/span&gt; и &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;last&lt;/span&gt; присутствуют в случае, если первая или последняя страница не попали в общий список из-за ограничения на его длину&lt;sup&gt;&lt;a name=&quot;ftnref-1&quot; href=&quot;#ftn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. Это ограничение можно установить, передав функции дополнительный аргумент:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$pages&lt;/span&gt; = nav_pages&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;nu0&quot;&gt;20&lt;/span&gt;, &amp;nbsp;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$total_rows&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// перечень страниц должен состоять не более чем из 10-ти ссылок (не считая special)&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Число записей на одной странице может, в свою очередь, регулироваться GET-параметром — можно указать функции использовать этот параметр и установить значение по умолчанию на случай, если он не задан:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$pages&lt;/span&gt; = nav_pages&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'N'&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;, &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// число записей забираем из $_GET[N] &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$total_rows&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// если же $_GET[N] пуст или вовсе не задан — выводим по 20 штук&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Наконец, последним аргументом можно передать адрес, отличный от &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$_SERVER&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'REQUEST_URI'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
В меню навигации ссылку, соответствующую текущей странице, логично визуально выделить и при этом убрать у неё атрибут &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;href&lt;/span&gt;&lt;sup&gt;&lt;a name=&quot;ftnref-2&quot; href=&quot;#ftn-2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;:
&lt;/p&gt;
&lt;div class=&quot;example&quot;&gt;
	&lt;nav&gt;
		Страницы:
		&lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?a=100&amp;b=200&amp;p=2&quot;&gt;предыдущая&lt;/a&gt;
		&lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?a=100&amp;b=200&quot;  &gt;1&lt;/a&gt;
		&lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?a=100&amp;b=200&amp;p=2&quot;  &gt;2&lt;/a&gt;
		&lt;a&gt;3&lt;/a&gt;
		&lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?a=100&amp;b=200&amp;p=4&quot;  &gt;4&lt;/a&gt;
		&lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?a=100&amp;b=200&amp;p=5&quot;  &gt;5&lt;/a&gt;
		&lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?a=100&amp;b=200&amp;p=4&quot;&gt;следующая&lt;/a&gt;
	&lt;/nav&gt;
&lt;/div&gt;
&lt;p&gt;
HTML-код такого меню можно получить из следующего шаблона (здесь и далее приводятся примеры для &lt;a href=&quot;http://webew.ru/articles/3609.webew&quot;&gt;шаблонизатора websun&lt;/a&gt;):
&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&amp;lt;nav&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Страницы: &lt;br /&gt;
&amp;nbsp; &amp;nbsp; {?*special.first*} &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{*special.first.url*}&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;в начало&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt; {?}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {?*special.prev*} &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{*special.prev.url*}&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;предыдущая&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt; {?}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {%*list*}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;?!*list:current*&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{*list:url*}&amp;quot;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;?&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;{*list:num*}&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {%}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {?*special.next*} &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{*special.next.url*}&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;следующая&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt; {?}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {?*special.last*} &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{*special.last.url*}&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;в конец&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt; {?}&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;&lt;/span&gt;/nav&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;style&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; /* для текущей страницы и остальных устанавливаем разные стили; отличаем их по наличию атрибута href */&lt;br /&gt;
&amp;nbsp; &amp;nbsp; nav a[href] { font-weight: normal; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; nav a:not([href]) { font-weight: bold; }&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Вместо номеров страниц можно указывать диапазон порядковых номеров самих записей:
&lt;/p&gt;
&lt;div class=&quot;example&quot;&gt;
	&lt;nav&gt;
    	Страницы:
     	&lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?a=100&amp;b=200&amp;p=2&quot;&gt;предыдущая&lt;/a&gt;
        &lt;a  rel=&quot;nofollow&quot; href=&quot;/catalogue/?a=100&amp;b=200&quot;  &gt;1-20&lt;/a&gt;
        &lt;a  rel=&quot;nofollow&quot; href=&quot;/catalogue/?a=100&amp;b=200&amp;p=2&quot;  &gt;21-40&lt;/a&gt;
        &lt;a  &gt;41-60&lt;/a&gt;
        &lt;a  rel=&quot;nofollow&quot; href=&quot;/catalogue/?a=100&amp;b=200&amp;p=4&quot;  &gt;61-80&lt;/a&gt;
        &lt;a  rel=&quot;nofollow&quot; href=&quot;/catalogue/?a=100&amp;b=200&amp;p=5&quot;  &gt;81-100&lt;/a&gt;
     &lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?a=100&amp;b=200&amp;p=4&quot;&gt;следующая&lt;/a&gt;
     &lt;/nav&gt;
&lt;/div&gt;
&lt;p&gt;В шаблоне для этого используются ключи &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;min&lt;/span&gt; и &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;max&lt;/span&gt;:&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&amp;lt;nav&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {%*list*}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;a&lt;/span&gt; ...&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;{*list:min*}–{*list:max*}&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {*list*%}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;&lt;/span&gt;/nav&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2&gt;&lt;a name=&quot;switches&quot;&gt;&lt;/a&gt;Меню переключателей на основе GET-параметра&lt;/h2&gt;
&lt;p&gt;
Встречаются ситуации, в которых нужно построить навигационное меню из однотипных ссылок, адреса которых отличаются только значением одного из GET-параметров&lt;sup&gt;&lt;a name=&quot;ftnref-3&quot; href=&quot;#ftn-3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;. При этом пункт меню, соответствующий текущей странице, должен визуально отличаться от остальных.
&lt;/p&gt;
&lt;p&gt;
Обычно такие ситуации возникают при наличии нескольких режимов отображения у одного и того же содержимого. Предположим, некий список может быть представлен построчно (по умолчанию), мелкой сеткой или крупными плашками:
&lt;/p&gt;
&lt;div class=&quot;example&quot;&gt;
	Вид:
	&lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?p=3&quot;&gt;построчно&lt;/a&gt;
	&lt;a&gt;сетка&lt;/a&gt;
	&lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?p=3&amp;view=plates&quot;&gt;плашки&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;
Для построения такого меню используется функция &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;nav_switches&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;, которой требуется передать имя GET-параметра и перечень пунктов меню, каждый из которых определяется текстом ссылки и значением параметра&lt;sup&gt;&lt;a name=&quot;ftnref-4&quot; href=&quot;#ftn-4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$cfg&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;''&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'построчно'&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// элемент с пустым ключом - по умолчанию&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'grid'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'сетка'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'plates'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'плашки'&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$menu&lt;/span&gt; = nav_switches&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'view'&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$cfg&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Например, для третьей страницы списка, представленного в виде сетки — адрес &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/catalogue/?p=3&amp;amp;view=grid&lt;/span&gt; — содержимое &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$menu&lt;/span&gt;&lt;/span&gt; таково:
&lt;/p&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Array&lt;br /&gt;
(&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [0] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [value] =&amp;gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [text] =&amp;gt; построчно&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [current] =&amp;gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /catalogue/?p=3&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [1] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [value] =&amp;gt; grid&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [text] =&amp;gt; сетка&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [current] =&amp;gt; 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /catalogue/?p=3&amp;amp;view=grid&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [2] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [value] =&amp;gt; plates&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [text] =&amp;gt; плашки&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [current] =&amp;gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /catalogue/?p=3&amp;amp;view=plates&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
)&lt;/div&gt;
&lt;p&gt;
Следует отметить, что все GET-параметры, кроме &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;view&lt;/span&gt;, сохраняют свои значения в адресах ссылок меню. При этом в ссылке на вид построчно &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;view&lt;/span&gt; отсутствует, поскольку этот вид выбран в качестве представления списка по умолчанию.
&lt;/p&gt;
&lt;p&gt;
HTML-шаблон меню выглядит примерно так:
&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&amp;lt;menu&amp;gt;&lt;/span&gt;&lt;br /&gt;
{%**}&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;?!*:current*&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{*:url*}&amp;quot;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;*:current*?!&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;{*:text*}&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt;{**%}&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;&lt;/span&gt;/menu&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Другой пример переключения на основе GET-параметра — регулировка количества записей на странице.
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// выводить по 10,20,50 и 100; по умолчанию - 20 &lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$cfg&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;''&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;20&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;50&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Здесь значение параметра — количество записей — служит сразу же и текстом ссылки (за исключением случая по умолчанию, когда значением является пустая строка).
&lt;/p&gt;
&lt;p&gt;
При переключении количества записей логично отправлять пользователя на первую страницу списка, а не на текущую, поэтому GET-параметр, соответствующий номеру страницы, следует из всех адресов удалить. Для этого нужно указать его имя третьим аргументом:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$menu&lt;/span&gt; = nav_switches&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'N'&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$cfg&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Для страницы &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/catalogue/?p=3&lt;/span&gt; &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$menu&lt;/span&gt;&lt;/span&gt; выглядит так:
&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Array&lt;br /&gt;
(&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [0] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [value] =&amp;gt; 10&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [text] =&amp;gt; 10&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [current] =&amp;gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /catalogue/?N=10&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [1] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [value] =&amp;gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [text] =&amp;gt; 20&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [current] =&amp;gt; 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /catalogue/&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [2] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [value] =&amp;gt; 50&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [text] =&amp;gt; 50&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [current] =&amp;gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /catalogue/?N=50&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [3] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [value] =&amp;gt; 100&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [text] =&amp;gt; 100&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [current] =&amp;gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /catalogue/?N=100&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
)&lt;/div&gt;
&lt;p&gt;
Последним аргументом можно передать адрес страницы, для которой строится меню, если это не &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$_SERVER&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'REQUEST_URI'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/span&gt;.
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;sort&quot;&gt;&lt;/a&gt;Переключение режимов сортировки&lt;/h2&gt;
&lt;p&gt;
Режим сортировки определяется не только параметром, по которому она осуществляется, но также и направлением (возрастание или убывание).
&lt;/p&gt;
&lt;p&gt;
Один из способов управления сортировкой через адрес страницы состоит в использовании GET-переменной, значение которой содержит указание на режим сортировки в формате &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;параметр направление&lt;/span&gt;. Например:
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;...&amp;amp;sort=price&lt;/span&gt; — сортировка по возрастанию цены&lt;/li&gt;
	&lt;li&gt;&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;...&amp;amp;sort=price+DESC&lt;/span&gt;&lt;sup&gt;&lt;a name=&quot;ftnref-5&quot; href=&quot;#ftn-5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; — сортировка по убыванию цены&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Обычно в меню сортировки каждому параметру соответствует по одной ссылке; та, что относится к выбранному в данный момент, выделяется визуально и при этом остается кликабельной, указывая на сортировку с противоположным направлением (это видно, если навести на нее указатель мыши). Например:
&lt;/p&gt;
&lt;style&gt;
	.example.sort a { margin-left: 1.5em ; }
	.example.sort a.ASC:after,
	.example.sort a.current.DESC:hover:after
		{ content:&quot; (возр.)&quot;; }
	.example.sort a.DESC:after,
	.example.sort a.current.ASC:hover:after
		{ content:&quot; (убыв.)&quot;; }
	&lt;/style&gt;
&lt;div class=&quot;example sort&quot;&gt;
	Сортировка:
	&lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?sort=price&quot; class=&quot;current DESC&quot;&gt;по цене&lt;/a&gt;
	&lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?sort=name&quot; class=&quot; ASC&quot;&gt;по названию&lt;/a&gt;
	&lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?sort=date+DESC&quot; class=&quot; DESC&quot;&gt;по дате&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;
Для генерации данных подобного меню служит функция
&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;nav_sort&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;, вызов которой в данном случае
будет выглядеть следующим образом:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$cfg&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'price'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'по цене DESC'&lt;/span&gt;, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'name'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'по названию'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'date'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'по дате DESC'&lt;/span&gt;,&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$menu&lt;/span&gt; = nav_sort&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'sort'&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$cfg&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// Третий аргумент — 'p' — указывает на имя GET-переменной, &lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// содержащей номер страницы, и необходим для того,&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// чтобы каждая ссылка всегда указывала на первую страницу списка.&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Содержимое &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$menu&lt;/span&gt;&lt;/span&gt; для страницы &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/catalogue/&lt;/span&gt; выглядит так:&lt;/p&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Array&lt;br /&gt;
(&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [0] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [is_current] =&amp;gt; 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [direction] =&amp;gt; DESC&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /t-ajax.php?sort=price&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [text] =&amp;gt; по цене&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [1] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [is_current] =&amp;gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [direction] =&amp;gt; ASC&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /t-ajax.php?sort=name&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [text] =&amp;gt; по названию&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [2] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [is_current] =&amp;gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [direction] =&amp;gt; DESC&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /t-ajax.php?sort=date+DESC&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [text] =&amp;gt; по дате&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
)&lt;/div&gt;
&lt;p&gt;
HTML-шаблон меню выглядит примерно так:
&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&amp;lt;menu&amp;gt;&lt;/span&gt;&lt;br /&gt;
{%**}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;kw3&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{?*:current*}current{*:current*?} {*:direction*}&amp;quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;kw3&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{*:url*}&amp;quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;{*:text*}&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
{**%}&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;&lt;/span&gt;/menu&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Каждая из ссылок в таком случае будет иметь класс &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;ASC&lt;/span&gt; или &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;DESC&lt;/span&gt;, а соответствующая текущему режиму сортировки — еще и класс &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;current&lt;/span&gt;. Это позволит эффективно управлять их внешним видом с помощью CSS:
&lt;/p&gt;
&lt;div class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;/* Текущий режим сортировки выделяем жирным. */&lt;/span&gt;&lt;br /&gt;
a&lt;span class=&quot;re1&quot;&gt;.current&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;font-weight&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;bold&lt;/span&gt;; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;coMULTI&quot;&gt;/* В зависимости от направления дописываем к тексту ссылки фрагмент &amp;quot;(возр.|убыв.)&amp;quot;. */&lt;/span&gt;&lt;br /&gt;
a&lt;span class=&quot;re1&quot;&gt;.ASC&lt;/span&gt;&lt;span class=&quot;re2&quot;&gt;:after&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;st0&quot;&gt;&amp;quot; (возр.)&amp;quot;&lt;/span&gt;; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
a&lt;span class=&quot;re1&quot;&gt;.DESC&lt;/span&gt;&lt;span class=&quot;re2&quot;&gt;:after&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;st0&quot;&gt;&amp;quot; (убыв.)&amp;quot;&lt;/span&gt;; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;coMULTI&quot;&gt;/* У выделенных ссылок ситуация сложнее:&lt;br /&gt;
при наведении мыши они должны показывать то направление, &lt;br /&gt;
которое станет действовать, если на ссылку нажать,&lt;br /&gt;
то есть обратное текущему. */&lt;/span&gt;&lt;br /&gt;
a&lt;span class=&quot;re1&quot;&gt;.current&lt;/span&gt;&lt;span class=&quot;re1&quot;&gt;.ASC&lt;/span&gt;&lt;span class=&quot;re2&quot;&gt;:hover&lt;/span&gt;&lt;span class=&quot;re2&quot;&gt;:after&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;st0&quot;&gt;&amp;quot; (убыв.)&amp;quot;&lt;/span&gt;; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
a&lt;span class=&quot;re1&quot;&gt;.current&lt;/span&gt;&lt;span class=&quot;re1&quot;&gt;.DESC&lt;/span&gt;&lt;span class=&quot;re2&quot;&gt;:hover&lt;/span&gt;&lt;span class=&quot;re2&quot;&gt;:after&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;content&lt;/span&gt;: &lt;span class=&quot;st0&quot;&gt;&amp;quot; (возр.)&amp;quot;&lt;/span&gt;; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
&lt;b&gt;В другом варианте организации меню&lt;/b&gt; отдельная ссылка соответствует каждому варианту направления сортировки, получается по две ссылки на каждый параметр:
&lt;/p&gt;
&lt;div class=&quot;example sort&quot;&gt;
	&lt;a rel=&quot;nofollow&quot; style=&quot;margin-left: 0&quot; href=&quot;/catalogue/?sort=price&quot;&gt;по возрастанию цены&lt;/a&gt;
	&lt;a rel=&quot;nofollow&quot; class=&quot;current&quot;&gt;по убыванию цены&lt;/a&gt;
	&lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?sort=date&quot;&gt;по дате, сначала старые&lt;/a&gt;
	&lt;a rel=&quot;nofollow&quot; href=&quot;/catalogue/?sort=date+DESC&quot;&gt;по дате, сначала новые&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;
Этому варианту соответствует такая конфигурация:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$cfg&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'price'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'по {возрастанию|убыванию} цены DESC'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'date'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'по дате, сначала {старые|новые}'&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Кроме того, понадобится немного другой шаблон:
&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&amp;lt;menu&amp;gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {%**}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;?*:current*&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;current&amp;quot;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;*:current*?&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;?*:url*&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{*:url*}&amp;quot;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;*:url*?&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;{*:text*}&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {**%}&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;&lt;/span&gt;/menu&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Последним аргументом функции можно передать адрес страницы, если это не &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$_SERVER&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'REQUEST_URI'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/span&gt;.
&lt;/p&gt;
&lt;div class=&quot;footnote&quot;&gt;
					&lt;div&gt;
						1.
						&lt;a name=&quot;ftn-1&quot; href=&quot;#ftnref-1&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
Если до последней страницы &amp;laquo;еще далеко&amp;raquo; (две или более от крайней в обычном списке), среди &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;special&lt;/span&gt; появляется также ссылка &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;forward&lt;/span&gt;. Удобна для случаев, когда нужно показать номер последней страницы (чтобы дать пользователю представление о том, сколько всего страниц) и отделить его от остальных, например, многоточием:
&lt;div class=&quot;example&quot;&gt;
	&lt;nav&gt;
		Страницы:
		&lt;a&gt;1&lt;/a&gt;
		&lt;a href=&quot;/catalogue/?a=100&amp;amp;b=200&amp;amp;p=2&quot; rel=&quot;nofollow&quot;&gt;2&lt;/a&gt;
		&lt;a href=&quot;/catalogue/?a=100&amp;amp;b=200&amp;amp;p=3&quot; rel=&quot;nofollow&quot;&gt;3&lt;/a&gt;
		&lt;a href=&quot;/catalogue/?a=100&amp;amp;b=200&amp;amp;p=4&quot; rel=&quot;nofollow&quot;&gt;...&lt;/a&gt;
		&lt;a href=&quot;/catalogue/?a=100&amp;amp;b=200&amp;amp;p=5&quot; rel=&quot;nofollow&quot;&gt;20&lt;/a&gt;
		&lt;a href=&quot;/catalogue/?a=100&amp;amp;b=200&amp;amp;p=4&quot; rel=&quot;nofollow&quot;&gt;следующая&lt;/a&gt;
	&lt;/nav&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;forward&lt;/span&gt; соответствует странице, следующей за последней из основного списка.
&lt;/p&gt;
&lt;p&gt;
Если &amp;laquo;уже далеко&amp;raquo; до первой страницы - в &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;special&lt;/span&gt; появляется ссылка &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;backward&lt;/span&gt;; соответствует странице, предшествующей самой первой из основного списка.
&lt;/p&gt;
					&lt;/div&gt;
					&lt;div&gt;
						2.
						&lt;a name=&quot;ftn-2&quot; href=&quot;#ftnref-2&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
						Отстутствие &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;href&lt;/span&gt; сделает ссылку некликабельной.
					&lt;/div&gt;
					&lt;div&gt;
						3.
						&lt;a name=&quot;ftn-3&quot; href=&quot;#ftnref-3&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
						Представление по умолчанию включается в случае отсутствия в адресе страницы GET-параметра, регулирующего представление.
					&lt;/div&gt;
					&lt;div&gt;
						4.
						&lt;a name=&quot;ftn-4&quot; href=&quot;#ftnref-4&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
						Есть также полная форма записи, в двух вариантах:
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// первый вариант&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$cfg&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;''&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'построчно'&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'grid'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'сетка'&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'plates'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'плашки'&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// второй вариант&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$cfg&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'value'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;''&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'построчно'&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'value'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'grid'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'сетка'&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'value'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'plates'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'плашки'&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;/div&gt;
Полную форму необходимо использовать, если  значениями являются целые числа и при этом в качестве текстов используются не значения, а что-то другое. Например:
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$cfg&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;2000&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;3000&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'пять тысяч'&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;7&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'семь тысяч'&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'десять тысяч'&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'value'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;20&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'двадцать тысяч'&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'value'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;30&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'тридцать тысяч'&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'value'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;40&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;40000&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'value'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;50&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;50000&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;/div&gt;
					&lt;/div&gt;
					&lt;div&gt;
						5.
						&lt;a name=&quot;ftn-5&quot; href=&quot;#ftnref-5&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
						&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;+&lt;/span&gt; — это URL-закодированный пробел. &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;ASC&lt;/span&gt; — по возрастанию (от &lt;i&gt;ascendant&lt;/i&gt;), &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;DESC&lt;/span&gt; — по убыванию (от &lt;i&gt;descendant&lt;/i&gt;), по аналогии с синтаксисом языка SQL.
					&lt;/div&gt;
					&lt;/div&gt;</description>
</item>
<item>
  <title>Простая функция для измерений скорости и использования памяти в PHP</title>
  <link>http://webew.ru/articles/5500.webew</link>
  <guid>http://webew.ru/articles/5500.webew</guid>
  <pubDate>Tue, 15 Dec 2015 22:13:43 +0300</pubDate>
  <description>&lt;!--Простая функция для измерения скорости и использования памяти в PHP--&gt;
&lt;p&gt;
Вниманию читателей предлагается простой программный интерфейс для сбора значений &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;microtime&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; и &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;memory_get_usage&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; и представления их в удобном для восприятия виде.
&lt;/p&gt;
&lt;p&gt;
Пользоваться &lt;a name=&quot;download&quot; href=&quot;http://webew.ru/f/tfG7HS39.php&quot; title=&quot;скачать код функции&quot;&gt;функцией&lt;/a&gt; очень легко. Нужно вызвать её в самом начале скритпа, а затем — после каждой интересующей операции, передав в качестве аргумента массив для записи и имя для конкретного измеряемого отрезка:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'benchmark.function.php'&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'start'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;co1&quot;&gt;// запускаем измерение &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$N&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;1000000&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$i&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; &lt;span class=&quot;re0&quot;&gt;$i&lt;/span&gt; &amp;lt; &lt;span class=&quot;re0&quot;&gt;$N&lt;/span&gt;; &lt;span class=&quot;re0&quot;&gt;$i&lt;/span&gt;++&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ; &lt;span class=&quot;co1&quot;&gt;// пустой цикл&lt;/span&gt;&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'i'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$j&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; &lt;span class=&quot;re0&quot;&gt;$j&lt;/span&gt; &amp;lt; &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;*&lt;span class=&quot;re0&quot;&gt;$N&lt;/span&gt;; &lt;span class=&quot;re0&quot;&gt;$j&lt;/span&gt;++&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ;&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'j'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$h&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; &lt;span class=&quot;re0&quot;&gt;$h&lt;/span&gt; &amp;lt; &lt;span class=&quot;nu0&quot;&gt;3&lt;/span&gt;*&lt;span class=&quot;re0&quot;&gt;$N&lt;/span&gt;; &lt;span class=&quot;re0&quot;&gt;$h&lt;/span&gt;++&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ;&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'h'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;Содержимое $BENCHMARK будет примерно следующим:&lt;/p&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Array&lt;br /&gt;
(&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [recent] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 1450175830.0469&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 973360&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 980464&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [total] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 376&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0.93&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0.94&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [list] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [start] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0.93&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0.94&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [i] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 63&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [j] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 141&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [h] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 188&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
)&lt;/div&gt;
&lt;p&gt;
&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;total&lt;/span&gt; — суммарные значения времени выполнения (в миллисекундах) и объема используемой памяти (в мегабайтах) от первого вызова функции до последнего. В &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;list&lt;/span&gt; содержатся значения по конкретным отрезкам.
&lt;/p&gt;
&lt;p&gt;
Именовать первый отрезок (в примере выше — &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;start&lt;/span&gt;) не обязательно; он будет содержать нулевое время, т.к. это первый вызов. Однако &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;start&lt;/span&gt; покажет затраты памяти на холостой запуск PHP-сценария&lt;sup&gt;&lt;a name=&quot;ftn-1&quot; href=&quot;#ftnref-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;
&lt;/p&gt;
Повторное указание одного и того же имени отрезка приводит к суммированию значений:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$i&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; ... &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ...&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'Cycle'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$j&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; ... &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ...&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'Cycle'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$h&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; ... &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ...&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'Cycle'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Cycle&lt;/span&gt; будет содержать сумму показателей для &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;i&lt;/span&gt;, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;j&lt;/span&gt; и &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;h&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
Измеряемый отрезок может быть прерывистым. Тогда каждую его часть нужно окружить вызовами &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;&lt;sup&gt;&lt;a name=&quot;ftn-2&quot; href=&quot;#ftnref-2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$i&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; &lt;span class=&quot;re0&quot;&gt;$i&lt;/span&gt; &amp;lt; &lt;span class=&quot;re0&quot;&gt;$N&lt;/span&gt;; &lt;span class=&quot;re0&quot;&gt;$i&lt;/span&gt;++&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ;&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'Cycle'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// ...&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// Здесь некий код, быстродействие которого отдельно не измеряем.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// Его измерения, однако, войдут в суммарные показатели.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// ...&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$h&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; &lt;span class=&quot;re0&quot;&gt;$h&lt;/span&gt; &amp;lt; &lt;span class=&quot;nu0&quot;&gt;3&lt;/span&gt;*&lt;span class=&quot;re0&quot;&gt;$N&lt;/span&gt;; &lt;span class=&quot;re0&quot;&gt;$h&lt;/span&gt;++&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ;&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'Cycle'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Cycle&lt;/span&gt; на этот раз будет содержать сумму показателей для &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;i&lt;/span&gt; и &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;h&lt;/span&gt;, а &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;total&lt;/span&gt; — по-прежнему измерения от первого до последнего вызова &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
Для отрезка можно указывать поясняющий текст, который войдет в состав массива с измерениями в качестве элемента &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;title&lt;/span&gt;&lt;sup&gt;&lt;a name=&quot;ftn-3&quot; href=&quot;#ftnref-3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$i&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; ... &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ...&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'i:1M'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$j&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; ... &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ...&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'j:2M'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$h&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; ... &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ...&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'h:3M'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Array&lt;br /&gt;
(&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [list] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [i] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 47&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [title] =&amp;gt; 1M&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [j] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [title] =&amp;gt; 2M&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [h] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [title] =&amp;gt; 3M&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
)&lt;/div&gt;
&lt;p&gt;
Внутри отрезка можно выделять дочерние, измерения по каждому из которых будут проводиться отдельно и суммироваться с измерениями основного&lt;sup&gt;&lt;a name=&quot;ftn-4&quot; href=&quot;#ftnref-4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. Имена дочерних отрезков отделяются от основного точкой, вложенность не ограничена:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$i&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; ... &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ...&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'Cycle.i'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$j&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; ... &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ...&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'Cycle.j'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$h&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; ... &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ...&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'Cycle.h:3M'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Array&lt;br /&gt;
(&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [recent] =&amp;gt; ...&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [total] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 376&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0.93&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0.94&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [list] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [start] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0.93&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0.94&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [Cycle] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 376&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [list] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [i] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 47&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [j] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 141&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [h] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 188&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [title] =&amp;gt; 3M&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
)&lt;/div&gt;
&lt;p&gt;
Дочерним отрезкам вместо явного определения имен можно указать  автоматическую нумерацию:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// Используется специальная конструкция &amp;quot;%+&amp;quot;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$i&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; ... &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ...&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'Cycle.%+'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$j&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; ... &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ...&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'Cycle.%+'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$h&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; ... &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ...&lt;br /&gt;
benchmark&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$BENCHMARK&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'Cycle.%+:Цикл № %+'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;co1&quot;&gt;// и в title - тоже&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Array&lt;br /&gt;
(&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; [list] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [start] =&amp;gt; ...&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [Cycle] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [list] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [0] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 63&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [1] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 125&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [2] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [time] =&amp;gt; 188&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [memory_peak] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [title] =&amp;gt; Цикл № 2&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
)&lt;/div&gt;
&lt;div class=&quot;footnote&quot;&gt;
&lt;p&gt;
1.&lt;a name=&quot;ftnref-1&quot; href=&quot;#ftn-1&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
За вычетом затрат на подключение benchmark-функции (которые, впрочем, несущественны).
&lt;/p&gt;
&lt;p&gt;
2.&lt;a name=&quot;ftnref-2&quot; href=&quot;#ftn-2&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
Вызов без указания имени отрезка сбрасывает внутренние значения счетчиков и обновляет суммарные показатели.
&lt;/p&gt;
&lt;p&gt;
3.&lt;a name=&quot;ftnref-3&quot; href=&quot;#ftn-3&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
Если отрезок прерывистый, используется вариант поясняющего текста, указанный последним.
&lt;/p&gt;
&lt;p&gt;
4.&lt;a name=&quot;ftnref-4&quot; href=&quot;#ftn-4&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
Можно сказать, что все поименованные отрезки являются дочерними по отношению к &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;total&lt;/span&gt;.
&lt;/p&gt;&lt;/div&gt;</description>
</item>
<item>
  <title>Согласованный AJAX-слой для веб-сайта</title>
  <link>http://webew.ru/articles/5268.webew</link>
  <guid>http://webew.ru/articles/5268.webew</guid>
  <pubDate>Tue, 30 Dec 2014 10:26:21 +0300</pubDate>
  <description>&lt;script&gt; var CONTENTS_LEVEL = 2 &lt;/script&gt;
&lt;p&gt;
Реакцией на действие пользователя может быть согласованное изменение содержимого нескольких блоков на странице, происходящее без её перезагрузки.
Вниманию читателей предлагается простой программный интерфейс для обновления указанных блоков (всех или части), который позволяет сформировать из них единый согласованный &lt;em&gt;AJAX-слой&lt;/em&gt;.
&lt;/p&gt;
&lt;p&gt;Чтобы реализовать на сайте согласованный AJAX-слой, нужно:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;составить список взаимно согласованных блоков&lt;/li&gt;
	&lt;li&gt;подключить &lt;a href=&quot;/f/yKv8BpnZ.js&quot; target=&quot;_blank&quot; title=&quot;AJAX-слой: javascript-библиотека&quot;&gt;небольшую javascript-библиотеку&lt;/a&gt; и установить на сайт специальный код&lt;sup&gt;&lt;a name=&quot;ftn-1&quot; href=&quot;#ftnref-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
	&lt;li&gt;подготовить серверную часть для AJAX-ответа&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Ярким примером сайта, которому необходим согласованный AJAX-слой, является интернет-магазин. Для него мы и рассмотрим технику внедрения.
&lt;/p&gt;
&lt;h2&gt;Определение состава AJAX-слоя&lt;/h2&gt;
&lt;p&gt;
Первый этап внедрения AJAX-слоя — понять, какие же, собственно, блоки в него входят и в каких случаях они должны обновляться. Для включения в слой каждому блоку требуется назначить имя (любая строка). Такой анализ нужно провести для всех страниц сайта, при этом имена блоков должны быть уникальными в рамках всего слоя.
&lt;/p&gt;
&lt;p&gt;
Типичный интернет-магазин имеет практически на всех страницах:
&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;
		Блок с общей информацией о содержимом корзины — назовем его &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;cart:brief&lt;/span&gt;.
		&lt;br&gt;
		Этот блок должен обновляться при изменении состава покупок: нажатии кнопки &amp;laquo;купить&amp;raquo;, авторизации пользователя, у которого была непустая корзина и т.д.
	&lt;/li&gt;
	&lt;li&gt;
		Зону авторизации: форма, кнопка &amp;laquo;войти&amp;raquo; и пр., или же, для авторизованных пользователей, некую личную информацию (приветствие и пр.) — &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;auth:brief&lt;/span&gt;.
		&lt;br&gt;
		Обновление требуется при успешной авторизации или регистрации пользователя.
	&lt;/li&gt;
	&lt;li&gt;
		Список товарных предложений, каждое из которых снабжено кнопкой &amp;laquo;купить&amp;raquo; или надписью &amp;laquo;товар в корзине&amp;raquo;. Участником слоя в данном случае является контейнер кнопки, ему дадим имя вида &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;buy:{id товара}&lt;/span&gt; (имя тогда будет уникальным, даже если на странице присутствует несколько товаров).
		&lt;br&gt;
		Наличие кнопки должно согласовываться с присутствием товара в корзине и обновляться при изменении списка покупок.
	&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Приписание блокам их имен осуществляется посредством установки значения атрибуту &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;data-*&lt;/span&gt;. Конкретное имя атрибута можно выбирать произвольно, главное, чтобы у всех элементов оно было одинаковым&lt;sup&gt;&lt;a name=&quot;ftn-2&quot; href=&quot;#ftnref-2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;
&lt;p&gt;
В случае примера можно сказать, что мы имеем дело с неким персональным слоем покупателя, поэтому назвать атрибут можно, например, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;data-personal-ajax&lt;/span&gt;. В HTML-код перечисленных выше блоков тогда нужно добавить атрибуты &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;data-personal-ajax=&amp;quot;cart:brief&amp;quot;&lt;/span&gt;, &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;data-personal-ajax=&amp;quot;auth:brief&amp;quot;&lt;/span&gt; и т.д.
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;init&quot;&gt;&lt;/a&gt;Установка кода слоя на страницу. Программный интерфейс для обновления.&lt;/h2&gt;
&lt;p&gt;
Для инициализации слоя на странице нужно подключить код библиотеки и создать объект слоя, который следует записать в глобальную переменную для использования в замыканиях. Это стоит сделать пораньше (например, в &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;).
&lt;/p&gt;
&lt;p&gt;В случае персонального слоя для интернет-магазина код может выглядеть так:&lt;/p&gt;
&lt;div class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; PERSONAL_AJAX_LAYER = &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; AjaxLayer&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'html_data_name'&lt;/span&gt;: &lt;span class=&quot;st0&quot;&gt;'personal-ajax'&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// имя data-атрибута &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'http_query_key'&lt;/span&gt;: &lt;span class=&quot;st0&quot;&gt;'personal_ajax'&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// ключ для AJAX-запросов&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'server'&lt;/span&gt;: &lt;span class=&quot;st0&quot;&gt;'/ajax-layer.php'&lt;/span&gt;, &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// адрес для AJAX-запросов&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
(Параметры &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;http_query_key&lt;/span&gt; и &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;server&lt;/span&gt; описаны в разделе, посвященном &lt;a href=&quot;#server&quot;&gt;серверной части&lt;/a&gt;.)
&lt;/p&gt;
&lt;p&gt;
Для обновления слоя нужно вызывать метод &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;.refresh()&lt;/span&gt;, указывая имена блоков, которые следует обновить, в виде массива. Например:
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;span class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;.&lt;span class=&quot;me1&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'cart'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'buy'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; — обновить все блоки, имя которых начинается с &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;cart&lt;/span&gt; или &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;buy&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;.&lt;span class=&quot;me1&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;/^&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;cart|buy&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;/&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; — то же самое, но в виде регулярного выражения&lt;/li&gt;
	&lt;li&gt;&lt;span class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;.&lt;span class=&quot;me1&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'buy*23570'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; — обновить блоки, имя которых начинается на &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;buy&lt;/span&gt; и затем содержит в себе &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;23570&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;.&lt;span class=&quot;me1&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; — полностью обновить AJAX-слой на данной странице&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Вызов метода &lt;span class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;.&lt;span class=&quot;me1&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; приводит к запросу с сервера актуального HTML-кода перечисленных блоков. (Подробности см. в разделе о &lt;a href=&quot;#server&quot;&gt;серверной части&lt;/a&gt;.)
&lt;/p&gt;
&lt;h2&gt;Интеграция с обработчиками событий&lt;/h2&gt;
&lt;p&gt;
В типичном случае события, которые должны вызывать обновление слоя, уже содержат отправку AJAX-запроса, снабженную собственной callback-функцией. Для интеграции слоя в обработчик нужно добавить внутрь этой функции вызов &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;.refresh()&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
Рассмотрим в качестве примера обработчик формы авторизации, отправка которой происходит по AJAX:
&lt;/p&gt;
&lt;div class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;$&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'body'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'form.auth'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'submit'&lt;/span&gt;, &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; query = $&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;serialize&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; address = ... ;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; post_callback = &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; ... &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; ;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $.&lt;span class=&quot;me1&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;query, address, post_callback&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;false&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
В функции, записанной в переменную &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;post_callback&lt;/span&gt;, проверяется ответ сервера, и в случае, если он говорит об успешной авторизации, еще одним запросом — с помощью &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;.refresh()&lt;/span&gt; — обновляется AJAX-слой:&lt;sup&gt;&lt;a name=&quot;ftn-3&quot; href=&quot;#ftnref-3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
&lt;/p&gt;
&lt;div class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; post_callback = &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// ... (проверяем ответ) ...&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// составляем набор блоков на обновление (в данном случае это легко, &amp;nbsp; &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// т.к. при авторизации нужно обновить все блоки без исключения)&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; patterns = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; PERSONAL_AJAX_LAYER.&lt;span class=&quot;me1&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;patterns&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Другой пример — обработчик кнопки &amp;laquo;купить&amp;raquo;. Нажатие на кнопку сопровождается отправкой на сервер запроса на добавление в корзину товара с данным id:
&lt;/p&gt;
&lt;div class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;$&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'body'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'.buy'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'click'&lt;/span&gt;, &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; id = ... ; &lt;span class=&quot;co1&quot;&gt;// id товара &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; query = ... ;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; address = ... ;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; post_callback = &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; ... &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; ;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $.&lt;span class=&quot;me1&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;query, address, post_callback&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;false&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
После проверки ответа нужно обновить блок с содержимым корзины. Сама кнопка в нормальном случае должна смениться надписью &amp;laquo;товар в корзине&amp;raquo;, поэтому также нужно обновить контейнер этой кнопки, но не контейнеры остальных:&lt;sup&gt;&lt;a name=&quot;ftn-4&quot; href=&quot;#ftnref-4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; очевидно, добавление в корзину товара никак не может повлиять на присутствие в ней других товаров.
&lt;/p&gt;
&lt;div class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; post_callback = &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// ... (проверки) ...&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; patterns = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'cart'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'buy*'&lt;/span&gt; + id &lt;span class=&quot;co1&quot;&gt;// кнопку заменяем только у этого товара&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; PERSONAL_AJAX_LAYER.&lt;span class=&quot;me1&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;patterns&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;;&lt;/div&gt;
&lt;h2&gt;&lt;a name=&quot;callback&quot;&gt;&lt;/a&gt;Callback-функции при обновлении слоя&lt;/h2&gt;
&lt;p&gt;
Можно назначить дополнительные действия, которыми будет сопровождаться обновление блоков. Для этого их список, передаваемый методу &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;.refresh()&lt;/span&gt;, нужно снабдить callback-функциями.
&lt;/p&gt;
&lt;p&gt;
Предположим, при нажатии кнопки &amp;laquo;купить&amp;raquo; она должна заменяться на надпись &amp;laquo;товар в корзине&amp;raquo; не сразу, а плавно исчезая. Cоответствующая запись в списке блоков, подлежащих обновлению, из строки  &lt;span class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'buy*'&lt;/span&gt; + id&lt;/span&gt; станет массивом, первым элементом которого будет вышеупомянутая строка, а вторым — callback-функция:
&lt;/p&gt;
&lt;div class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; post_callback = &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// ... (проверки) ...&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; layer_callback = &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; target, html &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; target.&lt;span class=&quot;me1&quot;&gt;fadeOut&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; target.&lt;span class=&quot;me1&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;html&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;fadeIn&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt; patterns = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'cart'&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// корзину описываем скалярной величиной, т.к. callback не нужен &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'buy*'&lt;/span&gt; + id, layer_callback &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// элемент для кнопки теперь массив из двух элементов&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; PERSONAL_AJAX_LAYER.&lt;span class=&quot;me1&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;patterns&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Callback-функция должна принимать два аргумента: первый — jQuery-объект элемента (в данном случае им выступает контейнер кнопки), второй — HTML-код для этого элемента, полученный с сервера.
&lt;/p&gt;
&lt;p&gt;
Стандартное (без callback) обновление слоя выполняется функцией
&lt;/p&gt;
&lt;div class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; target, html &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; target.&lt;span class=&quot;me1&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;html&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Callback-функция применяется ко всем элементам, соответствующим переданному с ней в паре шаблону.
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;server&quot;&gt;&lt;/a&gt;Серверная часть&lt;/h2&gt;
&lt;p&gt;
Как уже было сказано ранее, содержимое блоков получается с сервера отдельным HTTP-запросом.
&lt;/p&gt;
&lt;p&gt;
Этот запрос всегда делается методом POST и отправляется по одному и тому же пути, который указывается
при &lt;a href=&quot;#init&quot;&gt;создании объекта слоя&lt;/a&gt; в качестве параметра &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;server&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
Единственным параметром запроса является массив с именем, указанным в &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;http_query_key&lt;/span&gt; при создании объекта. Он содержит информацию о членах AJAX-слоя, присутствовавших на странице на момент формирования запроса.
&lt;/p&gt;
&lt;p&gt;
Для страницы, на которой имеются корзина, незаполненная форма авторизации и несколько товаров, POST-запрос будет выглядеть так:
&lt;/p&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Array(&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [personal_ajax] =&amp;gt; Array(&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [0] =&amp;gt; Array( [name] =&amp;gt; cart:brief )&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [1] =&amp;gt; Array( [name] =&amp;gt; buy:23570 &amp;nbsp;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [2] =&amp;gt; Array( [name] =&amp;gt; buy:13450 &amp;nbsp;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [3] =&amp;gt; Array( [name] =&amp;gt; buy:60389 &amp;nbsp;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [5] =&amp;gt; Array( [name] =&amp;gt; auth:brief, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [inputs] =&amp;gt; Array( [email] =&amp;gt; &amp;nbsp;[password] =&amp;gt; ) &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&amp;nbsp; &amp;nbsp; )&lt;br /&gt;
)&lt;/div&gt;
&lt;p&gt;
Ключ &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;name&lt;/span&gt; содержит имя блока и позволяет, таким образом, однозначно этот блок идентифицировать и сгенерировать для него HTML-код.
&lt;/p&gt;
&lt;p&gt;
В &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;inputs&lt;/span&gt; передаются текущие значения полей форм, если таковые имеются внутри блока. Их наличие позволяет при обновлении AJAX-слоя сохранять содержимое частично заполненных форм. (Если серверная часть написана на языке PHP, рекомендуется использовать &lt;a href=&quot;http://webew.ru/articles/5239.webew&quot; title=&quot;Генерация HTML-кода форм с помощью языка PHP&quot;&gt;специальное средство для генерации HTML-форм&lt;/a&gt;.)
&lt;/p&gt;
&lt;p&gt;
В ответ нужно вернуть массив похожей структуры — добавить каждому элементу ключ &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;html&lt;/span&gt;, в который записать HTML-код блоков:&lt;sup&gt;&lt;a name=&quot;ftn-5&quot; href=&quot;#ftnref-5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;
&lt;/p&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Array(&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [0] =&amp;gt; Array( [name] =&amp;gt; cart:brief, [html] =&amp;gt; ... )&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [1] =&amp;gt; Array( [name] =&amp;gt; buy:23570, &amp;nbsp;[html] =&amp;gt; &amp;lt;button ...&amp;gt;купить&amp;lt;/button&amp;gt; &amp;nbsp;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [2] =&amp;gt; Array( [name] =&amp;gt; buy:13450, &amp;nbsp;[html] =&amp;gt; &amp;lt;button ...&amp;gt;купить&amp;lt;/button&amp;gt; &amp;nbsp;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [3] =&amp;gt; Array( [name] =&amp;gt; buy:60389, &amp;nbsp;[html] =&amp;gt; товар в корзине &amp;nbsp;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [5] =&amp;gt; Array( [name] =&amp;gt; auth:brief, [html] =&amp;gt; &amp;lt;form class=&amp;quot;auth&amp;quot;&amp;gt;...&amp;lt;/form&amp;gt; )&lt;br /&gt;
)&lt;/div&gt;
&lt;p&gt;
Ответ должен быть предусмотрен для всех возможных состояний каждого из блоков, входящих в состав слоя.
&lt;/p&gt;
&lt;div class=&quot;footnote&quot;&gt;
&lt;p&gt;
1.&lt;a name=&quot;ftnref-1&quot; href=&quot;#ftn-1&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
Необходима также библиотека jQuery.
&lt;/p&gt;
&lt;p&gt;
2.&lt;a name=&quot;ftnref-2&quot; href=&quot;#ftn-2&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
На одной странице может существовать много AJAX-слоев, принадлежность к каждому из которых будет определяться наличием data-атрибута с определенным именем. При этом один и тот же блок может входить в состав нескольких слоев (имея data-атрибуты с соответствующими именами).
&lt;/p&gt;
&lt;p&gt;
3.&lt;a name=&quot;ftnref-3&quot; href=&quot;#ftn-3&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
Включить в архитектуру AJAX-слоя отдельный запрос потребовалось, чтобы отделить логику работы его механизма от собственно обработки конкретного события.
&lt;br&gt;
Также отдельный запрос необходим, если содержимое блоков генерируется на основе cookie, т.к. последние приходят на сервер в обновленном виде только со следующим запросом. &lt;!-- Первый запрос что-то изменяет, второй получает. ВАРИАНТ С ДВУМЯ ЗАПРОСАМИ ПО КОДУ ПРОЩЕ (МЕНЬШЕ &quot;ОБЩИХ&quot; МЕСТ ТИПА http_query_key) с двумя запросами легче, т.к. там не мешаются другие ключи. Не нужно везде вызывать функцию и мешать её вывод с другими ключами и пр. --&gt;
&lt;/p&gt;
&lt;p&gt;
4.&lt;a name=&quot;ftnref-4&quot; href=&quot;#ftn-4&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
Следует отметить, что использование строковой нотации вида &lt;span class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'buy*'&lt;/span&gt; + id&lt;/span&gt; может приводить к избыточному обновлению: например, в случае товара c id = 2 с сервера будет запрошен HTML-код не только для него, но и для товаров с любым id, содержащим двойку: 12, 23 и т.д.
&lt;br&gt;
Как правило, эта особенность не играет никакой роли. Но если этого все-таки требуется избежать, нужно использовать регулярное выражение — &lt;span class=&quot;code javascript&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; RegExp&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'^buy:'&lt;/span&gt; + id + &lt;span class=&quot;st0&quot;&gt;'$'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
5.&lt;a name=&quot;ftnref-5&quot; href=&quot;#ftn-5&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
Если ответ сервера для некоторого блока вообще не содержит ключа &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;html&lt;/span&gt;, при разборе ответа этот блок игнорируется и его содержимое в итоге не меняется.
&lt;/p&gt;&lt;/div&gt;</description>
</item>
<item>
  <title>Генерация HTML-кода форм с помощью языка PHP</title>
  <link>http://webew.ru/articles/5239.webew</link>
  <guid>http://webew.ru/articles/5239.webew</guid>
  <pubDate>Sat, 11 Oct 2014 02:44:27 +0400</pubDate>
  <description>&lt;h1&gt;
	Генерация HTML-кода форм с помощью языка PHP
&lt;/h1&gt;
&lt;script&gt;var CONTENTS_LEVEL = 2&lt;/script&gt;
&lt;p&gt;
	Построение формы с сохранением уже введённых значений
	— не такая уж простая задача,
	особенно если приходится иметь дело со
	списками значений для выбора
	или
	c полями, соответствующими массивам.
	Предлагаемые инструменты позволяют свести решение этой проблемы к описанию полей формы в виде простых конфигураций и подключению нужных HTML-шаблонов.
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;download&quot;&gt;&lt;/a&gt;Состав пакета&lt;/h2&gt;
&lt;p&gt;
	В состав инструментария входят:
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;функция для генерации данных полей (код доступен в виде отдельного &lt;a href=&quot;http://webew.ru/f/aWmieech.php&quot; title=&quot;make_form_data&quot;&gt;PHP-файла&lt;/a&gt;)&lt;/li&gt;
	&lt;li&gt;HTML-шаблоны полей (в виде &lt;a href=&quot;http://webew.ru/f/3CbwgFp4.zip&quot;&gt;архива&lt;/a&gt;)&lt;/li&gt;
	&lt;li&gt;обработчик шаблонов (ему посвящена отдельная статья, в которой и &lt;a href=&quot;//webew.ru/articles/3609.webew#download&quot; title=&quot;Легкий шаблонизатор на PHP - скачать&quot;&gt;опубликован его код&lt;/a&gt;)
&lt;/ul&gt;
&lt;h2&gt;Основные принципы составления конфигурации полей&lt;/h2&gt;
&lt;p&gt;
	Предположим, нужно получить вот такую форму:
&lt;/p&gt;
&lt;iframe src=&quot;/misha/articles/form/basic.php&quot; style=&quot;height: 505px&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;
	Для этого потребуется следующий код PHP:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;co2&quot;&gt;# 1. Получаем данные полей формы&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'make_form_data.php'&lt;/span&gt;; &lt;span class=&quot;co2&quot;&gt;# Подключаем код функции&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$cfg&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;co2&quot;&gt;# Составляем конфигурацию полей&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// первая группа&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'short_note'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'longer_text'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'some_file'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'flag'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// вторая группа&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'period'&lt;/span&gt; &amp;nbsp; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'values'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'день'&lt;/span&gt;, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'неделя'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'месяц'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'год'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'shape'&lt;/span&gt; &amp;nbsp; &amp;nbsp;=&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'values'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'round'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'круглый'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'square'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'квадратный'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'triangle'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'треугольный'&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'size'&lt;/span&gt; &amp;nbsp; &amp;nbsp; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'values'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'value'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;''&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'-- размер --'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'value'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'small'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'маленький'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'value'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'medium'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'средний'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'value'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'big'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'большой'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'color'&lt;/span&gt; &amp;nbsp; &amp;nbsp;=&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'attr'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'size'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// число видимых элементов &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// у &amp;lt;select&amp;gt; &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'values'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'black'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'white'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'red'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'красный'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'blue'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'синий'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'value'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'green'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'зеленый'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$FORMDATA&lt;/span&gt; = make_form_data&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$cfg&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;co2&quot;&gt;# Генерируем данные полей &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co2&quot;&gt;# с учетом параметров HTTP-запроса&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;co2&quot;&gt;# 2. Получаем HTML-код формы&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'websun.php'&lt;/span&gt;; &lt;span class=&quot;co2&quot;&gt;# Подключаем обработчик шаблонов &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$HTML&lt;/span&gt; = websun_parse_template_path&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$FORMDATA&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'form.tpl'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;co2&quot;&gt;# Подставляем данные &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;co2&quot;&gt;# в HTML-шаблон формы&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
	 С точки зрения составления конфигурации поля делятся на две группы:
&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;
		&lt;p&gt;
			&lt;em&gt;Одиночные поля&lt;/em&gt;:
		&lt;/p&gt;
		&lt;ul&gt;
			&lt;li&gt;&lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;text&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
			&lt;li&gt;&lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
			&lt;li&gt;&lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;textarea&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
			&lt;li&gt;&lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;file&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
		&lt;/ul&gt;
		&lt;p&gt;
			 Составить конфигурацию для этих полей очень просто — надо всего лишь указать их имена&lt;sup&gt;&lt;a name=&quot;ftnref-1&quot; href=&quot;#ftn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;p&gt;
			&lt;em&gt;Списки значений для выбора&lt;/em&gt;.
			Значения перечисляются в параметре &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;values&lt;/span&gt;, каждое из них может быть указано в формате &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'value'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'значение'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'подпись'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;, &lt;br&gt;
			&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'значение'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'подпись'&lt;/span&gt;&lt;/span&gt; или просто &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'значение'&lt;/span&gt;&lt;/span&gt;. Такими полями являются:
		&lt;/p&gt;
		&lt;ul&gt;
			&lt;li&gt;набор &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;radio&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
			&lt;li&gt;набор &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; для выбора нескольких значений одновременно&lt;/li&gt;
			&lt;li&gt;&lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;select&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; и &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;select&lt;/span&gt; multiple&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
В шаблоне формы каждому из полей соответствует запись вида &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;{* + *имя* | шаблон *}&lt;/span&gt;:
&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;form&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;method&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;&amp;lt;!-- - Для лучшей читаемости HTML-разметка таблицы не приводится --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Текст &lt;br /&gt;
&amp;nbsp; &amp;nbsp; {* + *short_note* &amp;nbsp;| fields/input.tpl *}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Многострочный текст &lt;br /&gt;
&amp;nbsp; &amp;nbsp; {* + *longer_text* | fields/textarea.tpl *}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Загрузка файла &lt;br /&gt;
&amp;nbsp; &amp;nbsp; {* + *some_file* &amp;nbsp; | fields/file.tpl *}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Флаг (вкл./выкл.) &lt;br /&gt;
&amp;nbsp; &amp;nbsp; {* + *flag* &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| fields/checkbox.tpl *}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Радиокнопки &lt;br /&gt;
&amp;nbsp; &amp;nbsp; {* + *period* &amp;nbsp; &amp;nbsp; &amp;nbsp;| fields/radios.tpl *}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Выбор нескольких значений &lt;br /&gt;
&amp;nbsp; &amp;nbsp; {* + *shape* &amp;nbsp; &amp;nbsp; &amp;nbsp; | fields/checkbox-multiple.tpl *}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Выпадающий список &lt;br /&gt;
&amp;nbsp; &amp;nbsp; {* + *size* &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| fields/select.tpl *}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Список с возможностьюодновременного выборанескольких значений&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {* + *color* &amp;nbsp; &amp;nbsp; &amp;nbsp; | fields/select-multiple.tpl *}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;button&amp;gt;&lt;/span&gt;&lt;/span&gt;Отправить&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2&gt;&lt;a name=&quot;attr&quot;&gt;&lt;/a&gt;Атрибуты полей&lt;/h2&gt;
	&lt;p&gt;
		Случается, что полю нужно присвоить какой-то атрибут, будь то класс, стиль или текст-заглушка. Сделать это можно, включив в конфигурацию поля параметр &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;attr&lt;/span&gt;, в котором нужные атрибуты следует перечислить в формате &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'имя'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'значение'&lt;/span&gt;&lt;/span&gt;&lt;sup&gt;&lt;a name=&quot;ftnref-2&quot; href=&quot;#ftn-2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.
		Например, конфигурация
	&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'input_2'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'attr'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'placeholder'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'пишите сюда'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'class'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'special'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'style'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'border: 2px solid #808080; padding: 2px'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
	&lt;p&gt;в сочетании с шаблоном &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;input.tpl&lt;/span&gt; даст:&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&lt;span class=&quot;kw3&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;text&amp;quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;input_2&amp;quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&lt;span class=&quot;kw3&quot;&gt;value&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; placeholder=&lt;span class=&quot;st0&quot;&gt;&amp;quot;пишите сюда&amp;quot;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;special&amp;quot;&lt;/span&gt; &amp;nbsp;&lt;span class=&quot;kw3&quot;&gt;style&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;border: 2px solid #808080; padding: 2px&amp;quot;&lt;/span&gt; &lt;br /&gt;
&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
	Значения атрибутов перед вставкой обрабатываются функцией &lt;a href=&quot;http://php.net/manual/ru/function.htmlspecialchars.php&quot;&gt;htmlspecialchars()&lt;/a&gt;.&lt;sup&gt;&lt;a name=&quot;ftnref-3&quot; href=&quot;#ftn-3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;keys&quot;&gt;&lt;/a&gt;Поля, соответствующие ассоциативным массивам&lt;/h2&gt;
	&lt;p&gt;
		Форма может содержать поля для указания нескольких значений одного и того же
		свойства, которые в HTTP-запросе удобно получать в виде ассоциативного подмассива.
	&lt;/p&gt;
	&lt;p&gt;
		Например, ограничение по цене удобно иметь в виде
	&lt;/p&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;[price] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [min] =&amp;gt; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [max] =&amp;gt; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;/div&gt;
	&lt;p&gt;
		Получить соответствующий набор полей можно, указав в конфигурации параметр
		&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;keys&lt;/span&gt;:
	&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'price'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'keys'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'min'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'max'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
	&lt;p&gt;
		В массиве для подстановки в шаблон добавится уровень вложенности, и к полям нужно будет обращаться по ключам:
	&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;{* + *price.min* | fields/input.tpl *}&lt;br /&gt;
{* + *price.max* | fields/input.tpl *}&lt;/div&gt;
	&lt;p&gt;
		Бывает нужно дифференцировать отдельные поля, указав те или иные индивидуальные свойства. В этом случае элементы массива &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;keys&lt;/span&gt; принимают формат описания конфигурации поля&lt;sup&gt;&lt;a name=&quot;ftnref-4&quot; href=&quot;#ftn-4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;.
		Например:
	&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'price'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'keys'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'min'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'attr'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'placeholder'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'от'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'max'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'attr'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'placeholder'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'до'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
	&lt;p&gt;
		Ключей может быть более двух: &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'keys'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'min'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'max'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'avg'&lt;/span&gt;, ...&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; и т.д.&lt;sup&gt;&lt;a name=&quot;ftnref-5&quot; href=&quot;#ftn-5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;
	&lt;/p&gt;
&lt;div class=&quot;footnote&quot;&gt;
					&lt;p&gt;
						1.
						&lt;a name=&quot;ftn-1&quot; href=&quot;#ftnref-1&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
				Сокращенной записи вида &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'имя'&lt;/span&gt;&lt;/span&gt; соответствует полная форма &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'имя'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;
					&lt;/p&gt;
					&lt;p&gt;
						2.
						&lt;a name=&quot;ftn-2&quot; href=&quot;#ftnref-2&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
			Атрибуты, которые обычно применяют без значений, указываются с дублированием:
			&lt;br&gt;
			&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'readonly'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'readonly'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'disabled'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'disabled'&lt;/span&gt;&lt;/span&gt; и т.п.
					&lt;/p&gt;
					&lt;p&gt;
						3.
						&lt;a name=&quot;ftn-3&quot; href=&quot;#ftnref-3&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Это удобно, в частности, когда в качестве атрибута нужно использовать JSON. Например:
	&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'attr'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'class'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'special'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'data-one'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'{&amp;quot;a&amp;quot;:1,&amp;quot;b&amp;quot;:2}'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'data-two'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'{&amp;quot;c&amp;quot;:20,&amp;quot;d&amp;quot;:30}'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
	Благодаря обработке &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;htmlspecialchars&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; кавычки из JSON встанут в значение атрибута без проблем.
					&lt;/p&gt;
					&lt;p&gt;
						4.
						&lt;a name=&quot;ftn-4&quot; href=&quot;#ftnref-4&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
			При этом параметры, не указанные в элементе &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;keys&lt;/span&gt;, наследуются от родительской конфигурации.
					&lt;/p&gt;
					&lt;p&gt;
						5.
						&lt;a name=&quot;ftn-5&quot; href=&quot;#ftnref-5&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
		Вложенность ключей может быть многоуровневой:
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'price'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'keys'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'min'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'max'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'keys'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'deep'&lt;/span&gt;, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'deeper'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'keys'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'very_deep'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
					&lt;/p&gt;
					&lt;/div&gt;</description>
</item>
<item>
  <title>Организация пространства адресов страниц веб-сайта средствами PHP и MySQL/MariaDB</title>
  <link>http://webew.ru/articles/5216.webew</link>
  <guid>http://webew.ru/articles/5216.webew</guid>
  <pubDate>Thu, 31 Jul 2014 06:05:09 +0400</pubDate>
  <description>&lt;!--h1&gt;
	Организация пространства адресов страниц веб-сайта средствами PHP и MySQL/MariaDB
&lt;/h1--&gt;
	&lt;script&gt; var CONTENTS_LEVEL = 2 &lt;/script&gt;
	&lt;p&gt;
		В статье излагается подход, при котором запросы к сайту обрабатываются централизованно (через один PHP-файл), а адреса и содержимое страниц хранятся в базе данных. При этом адрес страницы может быть динамическим, а содержимое — включать в себя метки для подстановки переменных. Странице также может быть назначен исполняемый PHP-код.
	&lt;/p&gt;
	&lt;p&gt;
		Настоящий подход опирается на два программных компонента: маршрутизатор и обработчик шаблонов. Они будут описаны в статье далее.
	&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;rewrite&quot;&gt;&lt;/a&gt;Виртуальное пространство адресов и централизация обработки запросов&lt;/h2&gt;
	&lt;p&gt;
		При данном подходе адреса страниц не привязаны к файловой системе, поэтому такое адресное пространство можно называть &lt;i&gt;виртуальным&lt;/i&gt;.
	&lt;/p&gt;
	&lt;p&gt;
		Для организации виртуального пространства адресов прежде всего нужно изменить обычное поведение веб-сервера, при котором он интерпретирует адреса запрашиваемых страниц как пути к физическим файлам и каталогам.
		Вместо этого от веб-сервера требуется, чтобы при получении HTTP-запроса он исполнял некоторый PHP-код и использовал результат работы этого кода для формирования HTTP-ответа.
	&lt;/p&gt;
	&lt;p&gt;
		Исключение составляют реально существующие физические файлы (например, изображения, и др.), которые серверу следует продолжать отдавать напрямую, не задействуя PHP.
	&lt;/p&gt;
	&lt;h3&gt;&lt;a name=&quot;apache&quot;&gt;&lt;/a&gt;Настройка Apache&lt;/h3&gt;
	&lt;p&gt;
		Описанная задача решается с помощью &lt;a href=&quot;http://httpd.apache.org/docs/current/mod/mod_rewrite.html&quot;&gt;модуля mod_rewrite&lt;/a&gt;. Один из способов — разместить в корневом каталоге веб-сервера файл &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;.htaccess&lt;/span&gt; примерно следующего содержания&lt;sup&gt;&lt;a name=&quot;ftn-1&quot; href=&quot;#ftnref-1&quot;&gt;1&lt;/a&gt;,&lt;a name=&quot;ftn-2&quot; href=&quot;#ftnref-2&quot;&gt;2&lt;/a&gt;,&lt;a name=&quot;ftn-3&quot; href=&quot;#ftnref-3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;:
	&lt;/p&gt;
&lt;div class=&quot;code apache&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;RewriteEngine&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;on&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;RewriteCond&lt;/span&gt; %&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;REQUEST_FILENAME&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; !-f &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;OR&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;RewriteCond&lt;/span&gt; %&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;REQUEST_FILENAME&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; \.php$&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;RewriteRule&lt;/span&gt; .* _showpage.php&lt;/div&gt;
	&lt;h3&gt;&lt;a name=&quot;nginx&quot;&gt;&lt;/a&gt;Настройка nginx&lt;/h3&gt;
	&lt;p&gt;
		Директивы для nginx выглядят следующим образом:
	&lt;/p&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;set $vertex /_showpage.php;&lt;br /&gt;
set $php_socket unix:/run/php/php5.6-fpm.sock;&lt;br /&gt;
&lt;br /&gt;
location / {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; index $vertex; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; error_page 404 = @vertex;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; location ~ \.php$ {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 404;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
location @vertex {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fastcgi_pass $php_socket;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fastcgi_param SCRIPT_FILENAME $document_root$vertex;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; include fastcgi_params;&lt;br /&gt;
}&lt;/div&gt;
&lt;h2&gt;&lt;a name=&quot;router&quot;&gt;&lt;/a&gt;Маршрутизатор&lt;/h2&gt;
	&lt;p&gt;
	Любой сайт есть совокупность страниц, имеющих адреса. Механизм сайта должен уметь анализировать приходящий HTTP-запрос и определять, к какой конкретно странице он относится.
	&lt;/p&gt;
	&lt;p&gt;
	Средство, позволяющее задать пространство адресов страниц и сопоставляющее адрес приходящего запроса этому пространству, называется &lt;em&gt;маршрутизатором&lt;/em&gt; (или &lt;em&gt;роутером&lt;/em&gt;).
	&lt;/p&gt;
	&lt;p&gt;
	В рамках настоящего подхода результатом работы маршрутизатора является HTTP-код ответа и данные для генерации HTML-кода страницы. Эти данные затем передаются обработчику шаблонов, который подставляет их в шаблон, формируя таким образом конечный HTML:
	&lt;/p&gt;
	&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$mysqli&lt;/span&gt; = mysqli_connect&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; ... &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;co1&quot;&gt;// можно также использовать mysql_connect&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'router.php'&lt;/span&gt;; &lt;span class=&quot;co1&quot;&gt;// подключаем код маршрутизатора&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$router_cfg&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; ... &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// перечисляем настройки маршрутизатора (см. ниже)&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$R&lt;/span&gt; = &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; Router&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$router_cfg&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;co1&quot;&gt;// создаем объект маршрутизатора &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$R&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;analyzeURL&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;co1&quot;&gt;// проводим анализ адреса; в результате объект &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// содержит данные страницы - свойство pageData &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// и путь к файлу с шаблоном - свойство template&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'websun.php'&lt;/span&gt;; &lt;span class=&quot;co1&quot;&gt;// подключаем код шаблонизатора &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$HTML&lt;/span&gt; = websun_parse_template_path&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// формируем HTML-код страницы&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$R&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;pageData&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// данные страницы для подстановки&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$R&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;template&lt;/span&gt; &amp;nbsp;&lt;span class=&quot;co1&quot;&gt;// путь к файлу с шаблоном&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;
&lt;span class=&quot;kw3&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$HTML&lt;/span&gt;;&lt;/div&gt;
	&lt;p&gt;
	Код маршрутизатора можно &lt;a name=&quot;download&quot; href=&quot;http://webew.ru/f/GJxXJwkA.php&quot;&gt;скачать одним файлом&lt;/a&gt; (требуется также &lt;a href=&quot;http://webew.ru/articles/3237.webew#download&quot; title=&quot;Удобные функции для работы с MySQL&quot;&gt;библиотека для работы с MySQL&lt;/a&gt;), код шаблонизатора можно скачать &lt;a href=&quot;http://webew.ru/articles/3609.webew&quot; title=&quot;Легкий шаблонизатор на PHP&quot;&gt;здесь&lt;/a&gt;. Техника использования будет подробно описана ниже.
	&lt;/p&gt;
&lt;h2&gt;Организация хранения страниц&lt;/h2&gt;
   &lt;p&gt;
	По большому счету, страница сайта — это HTML-код, имеющий адрес.
	&lt;/p&gt;
	&lt;p&gt;
	HTML-код страницы всегда имеет определенную структуру: каркас остается неизменным, а меняются лишь некоторые части. Обычно его можно описать следующим шаблоном:
	&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc0&quot;&gt;&amp;lt;!DOCTYPE HTML&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;&lt;/span&gt;{* заголовок *}&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;description&amp;quot;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{* описание для поисковых систем *}&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;keywords&amp;quot;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{* ключевые слова *}&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;&amp;lt;!-- далее может следовать подключение CSS и javascript-файлов и др. --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {* содержимое *}&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
	&lt;p&gt;
	С этой точки зрения &lt;i&gt;страницу сайта можно считать некой сущностью, уникально идентифицируемой адресом, которая имеет заголовок и содержимое, а также ключевые слова и описание для поисковых систем&lt;/i&gt;. Такие сущности удобно хранить в виде записей (строк) в таблице базы данных, а универсальный шаблон для подстановки — в виде отдельного файла.
	&lt;/p&gt;
	&lt;p&gt;
	Рассмотрим конфигурацию маршрутизатора в самом простом случае:
	&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$router_cfg&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'table'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'pages'&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// имя таблицы со страницами&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'template'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'$/templates/_page.tpl'&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// путь к файлу шаблона &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;co1&quot;&gt;// ($ - корневой каталог веб-сервера)&lt;/span&gt;&lt;/div&gt;
	&lt;p&gt;
	Таблица &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;pages&lt;/span&gt; должна иметь следующий минимальный набор колонок:
	&lt;/p&gt;
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CREATE TABLE&lt;/span&gt; pages &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; url &lt;span class=&quot;kw2&quot;&gt;VARCHAR&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;NOT NULL&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; title &lt;span class=&quot;kw2&quot;&gt;TEXT&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; description &lt;span class=&quot;kw2&quot;&gt;TEXT&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; keywords &lt;span class=&quot;kw2&quot;&gt;TEXT&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; content &lt;span class=&quot;kw2&quot;&gt;MEDIUMTEXT&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; code &lt;span class=&quot;kw2&quot;&gt;TEXT&lt;/span&gt;, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;-- назначение полей &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; template &lt;span class=&quot;kw2&quot;&gt;VARCHAR&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;-- code, template и headers &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; headers &lt;span class=&quot;kw2&quot;&gt;TEXT&lt;/span&gt;, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;co1&quot;&gt;-- разъясняется далее&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;UNIQUE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;url&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
	&lt;p&gt;Шаблон страницы содержит метки для подстановки данных:&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc0&quot;&gt;&amp;lt;!DOCTYPE HTML&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;&lt;/span&gt;{* + &amp;gt;*title* *}&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;description&amp;quot;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{* + &amp;gt;&lt;/span&gt;*description* *}&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&amp;lt;meta name=&amp;quot;&lt;/span&gt;keywords&lt;span class=&quot;st0&quot;&gt;&amp;quot; content=&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;* + &lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;*keywords* *}&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;&amp;lt;!-- далее может следовать подключение CSS и javascript-файлов и др. --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {* + &amp;gt;*content* *}&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
	&lt;p&gt;Более подробно языковые конструкции шаблона обсуждаются ниже.&lt;/p&gt;
&lt;h2&gt;Страницы со статическим адресом&lt;/h2&gt;
	&lt;p&gt;
	Перейдем теперь непосредственно к технике создания страниц и рассмотрим самый простой случай — страницу со статическим адресом.
	&lt;/p&gt;
	&lt;p&gt;
	Для иллюстрации этого примера как нельзя лучше подходит главная страница, которая есть у любого сайта. Чтобы создать главную страницу, необходимо вставить в таблицу &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;pages&lt;/span&gt; вот такую строку:
	&lt;/p&gt;
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; pages &lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; url = &lt;span class=&quot;st0&quot;&gt;'/'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; title = &lt;span class=&quot;st0&quot;&gt;'webew.ru — портал о веб-технологиях'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; description = &lt;span class=&quot;st0&quot;&gt;'Портал посвящен веб-технологиям.&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Здесь можно задать вопросы или поделиться своими идеями'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; keywords = &lt;span class=&quot;st0&quot;&gt;'веб-технологии, php, mysql, html, css, javascript'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; content = &lt;span class=&quot;st0&quot;&gt;'&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;h1&amp;gt;Вас приветствует webew.ru&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;h2&amp;gt;Последние статьи&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;h2&amp;gt;Новые темы и комментарии&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;footer&amp;gt;2014 &amp;amp;copy; webew.ru&amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; '&lt;/span&gt;;&lt;/div&gt;
   &lt;p&gt;
   Кириллические (и другие нелатинские) символы в адресах страниц следует указывать без url-кодирования:
   &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/мы&lt;/span&gt;, а не &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/%D0%BC%D1%8B&lt;/span&gt;, и т.п.
   &lt;/p&gt;
   &lt;p&gt;
   GET-паметры не считаются частью адреса страницы. Другими словами, адреса &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/page.html&lt;/span&gt;, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/page.html?a=1&lt;/span&gt; и &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/page.html?b=2&amp;amp;c=3&lt;/span&gt; с точки зрения маршрутизатора соответствуют одной и той же странице. (Это, однако, вовсе не означает, что GET-параметры нельзя использовать: с ними следует работать, назначив странице исполняемый PHP-код.)
   &lt;/p&gt;
&lt;h2&gt;Переменные в данных страницы. Назначение странице исполняемого кода.&lt;/h2&gt;
	&lt;p&gt;
	Вообще говоря, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;title&lt;/span&gt;, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;description&lt;/span&gt;, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;keywords&lt;/span&gt; и &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;content&lt;/span&gt; страниц сами по себе обрабатываются как полноценные шаблоны и могут содержать метки для подстановки переменных, наряду с прочими инструкциями. Например:
	&lt;/p&gt;
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; pages &lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; url = &lt;span class=&quot;st0&quot;&gt;'/'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; title = &lt;span class=&quot;st0&quot;&gt;'{*SITENAME*} — портал о веб-технологиях'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; description = &lt;span class=&quot;st0&quot;&gt;'Портал посвящен веб-технологиям.&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Здесь можно задать вопросы или поделиться своими идеями'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; keywords = &lt;span class=&quot;st0&quot;&gt;'веб-технологии, php, mysql, html, css, javascript'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; content = &lt;span class=&quot;st0&quot;&gt;'&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;h1&amp;gt;Вас приветствует {*SITENAME*}&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;h2&amp;gt;Последние статьи&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {* + $/mainpage/newarticles.tpl *}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;h2&amp;gt;Новые темы и комментарии&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {* + $/mainpage/newposts.tpl *}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;footer&amp;gt;{*year*} &amp;amp;copy; {*SITENAME*}&amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; '&lt;/span&gt;;&lt;/div&gt;
	&lt;p&gt;
	Инструкция вида &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;{* + $/mainpage/newarticles.tpl *}&lt;/span&gt; предписывает вызвать вложенный шаблон, находящийся по адресу &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;mainpage/newarticles.tpl&lt;/span&gt; относительно корневого каталога веб-сервера (сокращение &amp;quot;$&amp;quot;)&lt;sup&gt;&lt;a name=&quot;ftn-4&quot; href=&quot;#ftnref-4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. Также поддерживаются условия, циклы и многое другое&lt;sup&gt;&lt;a name=&quot;ftn-5&quot; href=&quot;#ftnref-5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;; подробнее эти возможности описаны в уже упоминавшейся выше &lt;a href=&quot;http://webew.ru/articles/3609.webew&quot; title=&quot;Легкий шаблонизатор на PHP&quot;&gt;статье про обработчик шаблонов&lt;/a&gt;.&lt;sup&gt;&lt;a name=&quot;ftn-6&quot; href=&quot;#ftnref-6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;
	&lt;/p&gt;
	&lt;p&gt;
	Теперь о том, как же задавать значения для подстановки.
	&lt;/p&gt;
	&lt;p&gt;
	Посмотрим еще раз, как выглядит вызов обработки шаблона:
	&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$HTML&lt;/span&gt; = websun_parse_template_path&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$R&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;pageData&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// данные страницы для подстановки&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$R&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;template&lt;/span&gt; &amp;nbsp;&lt;span class=&quot;co1&quot;&gt;// путь к шаблону&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
	&lt;p&gt;
	Массивом для подстановки служит свойство &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;pageData&lt;/span&gt; объекта маршрутизатора.
	&lt;/p&gt;
	&lt;p&gt;
	&lt;i&gt;Каждой странице можно назначить исполняемый PHP-код&lt;/i&gt;. Этот код может выполнять совершенно любые действия (никакие ограничения не накладываются), но прежде всего он используется как раз для заполнения массива &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;pageData&lt;/span&gt;.
	&lt;/p&gt;
	&lt;p&gt;
	Назначить исполняемый код можно несколькими способами.
	&lt;/p&gt;
	&lt;p&gt;
	Первый способ — записать в поле &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;code&lt;/span&gt; страницы путь к некоторому PHP-файлу. Например:
	&lt;/p&gt;
	&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; pages &lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; url = &lt;span class=&quot;st0&quot;&gt;'/'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; code = &lt;span class=&quot;st0&quot;&gt;'$/mainpage/get-data.php'&lt;/span&gt;;&lt;/div&gt;
	&lt;p&gt;Этот файл будет подключен маршрутизатором с помощью &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;require&lt;/span&gt;&lt;/span&gt;.&lt;sup&gt;&lt;a name=&quot;ftn-7&quot; href=&quot;#ftnref-7&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;
	&lt;/p&gt;
	&lt;p&gt;
	Предположим, на главной странице нужно показать общее количество опубликованных статей и сообщений:
	&lt;/p&gt;
	&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; pages &lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; url = &lt;span class=&quot;st0&quot;&gt;'/'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; content = &lt;span class=&quot;st0&quot;&gt;'&amp;lt;h1&amp;gt;...&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;p&amp;gt;Статьи: {*articles_total*}, сообщения: {*posts_total*}.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;footer&amp;gt;...&amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; '&lt;/span&gt;;&lt;/div&gt;
	&lt;p&gt;
	Тогда содержимое &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;mainpage/get-data.php&lt;/span&gt; будет примерно таким:
	&lt;/p&gt;
	&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$arts&lt;/span&gt; = ...; &amp;nbsp;&lt;span class=&quot;co1&quot;&gt;// тут некоторым образом получаем&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$posts&lt;/span&gt; = ...; &lt;span class=&quot;co1&quot;&gt;// общее количество статей и сообщений&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// а теперь записываем полученную информацию в объект маршрутизатора&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;pageData&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;articles_total&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$arts&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;pageData&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;posts_total&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$posts&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;pageData&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;SITENAME&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span class=&quot;st0&quot;&gt;&amp;quot;webew.ru&amp;quot;&lt;/span&gt;; &lt;span class=&quot;co1&quot;&gt;// добавляем в массив также &lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;pageData&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;year&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'Y'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;co1&quot;&gt;// элементы с ключами SITENAME и year&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw2&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/div&gt;
	&lt;p&gt;
	Как видно из примера, обращение к объекту маршрутизатора осуществляется через ссылку &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;&lt;/span&gt;&lt;sup&gt;&lt;a name=&quot;ftn-8&quot; href=&quot;#ftnref-8&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;.
	&lt;/p&gt;
	&lt;p&gt;
	Следует отметить, что &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;title&lt;/span&gt;, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;description&lt;/span&gt;, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;keywords&lt;/span&gt; и &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;content&lt;/span&gt; страниц также содержатся в массиве &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;pageData&lt;/span&gt;, но &lt;i&gt;изменять эти элементы непосредственно в исполняемом коде не рекомендуется&lt;/i&gt;.
	&lt;/p&gt;
	&lt;p&gt;
	Глобальные переменные, при необходимости, делаются доступными с помощью инструкции &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;global&lt;/span&gt;&lt;/span&gt; (аналогично тому, как это делается в функциях и классах).
	&lt;/p&gt;
	&lt;p&gt;
	Второй способ назначить странице исполняемый код — это записать его прямо в поле &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;code&lt;/span&gt;, заключив в &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;:
	&lt;/p&gt;
	&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; pages &lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; url = &lt;span class=&quot;st0&quot;&gt;'/'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; content = &lt;span class=&quot;st0&quot;&gt;'&amp;lt;h1&amp;gt;...&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;p&amp;gt;Статьи: {*articles_total*}, сообщения: {*posts_total*}.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;footer&amp;gt;...&amp;lt;/footer&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; '&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; code = &lt;span class=&quot;st0&quot;&gt;'&amp;lt;?php&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $arts = ...;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $posts = ...;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $this-&amp;gt;pageData[&amp;quot;articles_total&amp;quot;] = $arts;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $this-&amp;gt;pageData[&amp;quot;posts_total&amp;quot;] = $posts;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $this-&amp;gt;pageData[&amp;quot;SITENAME&amp;quot;] = &amp;quot;webew.ru&amp;quot;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; $this-&amp;gt;pageData[&amp;quot;year&amp;quot;] = date(Y);&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ?&amp;gt;'&lt;/span&gt; ;&lt;/div&gt;
	&lt;p&gt;
	Есть и третий способ. О нем будет рассказано в следующем разделе.
	&lt;/p&gt;
&lt;h2&gt;Страницы с динамическим адресом&lt;/h2&gt;
	&lt;p&gt;
	Страница может обслуживать набор однородных сущностей.
	&lt;/p&gt;
	&lt;p&gt;
	Предположим, сообщения, публикуемые на сайте, имеют адрес вида &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/posts/(id сообщения).html&lt;/span&gt;. Тогда соответствующая запись в таблице будет выглядеть примерно так:&lt;sup&gt;&lt;a name=&quot;ftn-9&quot; href=&quot;#ftnref-9&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;
	&lt;/p&gt;
	&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; pages &lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; url = &lt;span class=&quot;st0&quot;&gt;'/posts/(&lt;span class=&quot;es0&quot;&gt;\d&lt;/span&gt;+).html'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; code = &lt;span class=&quot;st0&quot;&gt;'Posts-&amp;gt;getData(1) [post]'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; title = &lt;span class=&quot;st0&quot;&gt;'{*post.title*}'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; description = &lt;span class=&quot;st0&quot;&gt;'{*post.snippet*}'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; keywords = &lt;span class=&quot;st0&quot;&gt;'{*post.tags*}'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; content = &lt;span class=&quot;st0&quot;&gt;'&amp;lt;h1&amp;gt;{*post.title*}&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;p class=&amp;quot;date&amp;quot;&amp;gt;{*post.date*}&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;div class=&amp;quot;text&amp;quot;&amp;gt;{*post.text*}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; '&lt;/span&gt;;&lt;/div&gt;
	&lt;p&gt;
	Здесь в качестве &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;url&lt;/span&gt; страницы указано &lt;a href=&quot;http://php.net/book.pcre.php&quot;&gt;Perl-совместимое регулярное выражение (PCRE)&lt;/a&gt;.
	&lt;/p&gt;
	&lt;p&gt;
	Следует отметить, однако, что в данном случае по одному лишь виду пути  запроса нельзя определить, что отдать в ответ — нужно еще как минимум убедиться в том, что имеется конкретная сущность (в данном случае сообщение), а также получить ее данные. Для этого нужно назначить странице исполняемый PHP-код.
	&lt;/p&gt;
	&lt;p&gt;
	&lt;a name=&quot;code-3&quot;&gt;&lt;/a&gt;
	Запись &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Posts-&amp;gt;getData(1) [post]&lt;/span&gt;, содержащаяся в &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;code&lt;/span&gt;, реализует вышеупомянутый третий способ назначения странице исполняемого кода и в совокупности с &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;url = &lt;span class=&quot;st0&quot;&gt;'/posts/(&lt;span class=&quot;es0&quot;&gt;\d&lt;/span&gt;+).html'&lt;/span&gt;&lt;/span&gt; означает буквально следующее: &amp;laquo;проанализировать адрес запроса регулярным выраженем &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;^/posts/(\d+).html$&lt;/span&gt;&lt;sup&gt;&lt;a name=&quot;ftn-10&quot; href=&quot;#ftnref-10&quot;&gt;10&lt;/a&gt;&lt;/sup&gt;, в случае совпадения создать объект класса &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Posts&lt;/span&gt; и вызвать его метод &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;getData&lt;/span&gt;, передав методу в качестве аргумента элемент массива вхождений с индексом &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;/span&gt; (то есть, строку, соответствующую первой паре скобок регулярного выражения); если результат работы &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;getData&lt;/span&gt; не пуст — записать его в &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;pageData&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'post'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/span&gt; объекта маршрутизатора&amp;raquo;.
	&lt;/p&gt;
	&lt;p&gt;
	Можно также использовать запись вида &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Posts-&amp;gt;getData(1) [post] $/posts/single.php&lt;/span&gt;, которая, в дополнение к вышеперечисленному, предписывает в случае успеха подключить файл &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;posts/single.php&lt;/span&gt;&lt;sup&gt;&lt;a name=&quot;ftn-11&quot; href=&quot;#ftnref-11&quot;&gt;11&lt;/a&gt;&lt;/sup&gt;.
	&lt;/p&gt;
	&lt;p&gt;
	Нулевой элемент массива вхождений всегда содержит полный путь запроса без ведущего слэша, поэтому при необходимости анализа полного пути можно обращаться к нулевому элементу: &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Posts-&amp;gt;getData(0)&lt;/span&gt;.
	Если индекс не указан — &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Posts-&amp;gt;getData()&lt;/span&gt; — в качестве аргумента методу будет передан весь массив вхождений целиком.
	&lt;/p&gt;
&lt;h2&gt;Альтернативные шаблоны страниц&lt;/h2&gt;
	&lt;p&gt;
	Отдельным страницам можно назначать альтернативные шаблоны для каркаса HTML-разметки.
	&lt;/p&gt;
	&lt;p&gt;
	Представим себе, что на всех страницах сайта, кроме главной, присутствует левая колонка, незименная от страницы к странице:
	&lt;/p&gt;
	&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc0&quot;&gt;&amp;lt;!DOCTYPE HTML&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;/span&gt;...&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;&amp;lt;!-- header одинаковый у всех страниц без исключения, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;поэтому его вынесем в отдельный шаблон --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {* + $/templates/header.tpl *} &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;left-column&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;&amp;lt;!-- левая колонка не обязательно статична по своему содержимому&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;здесь вполне могут быть переменные, например: --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {*left_menu*}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;center-column&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;&amp;lt;!-- а здесь собственно содержимое страницы - &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;то, что в ячейке content таблицы в БД --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {* +&amp;gt; *content* *}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;&amp;lt;!-- footer - аналогично header --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {* + $/templates/footer.tpl *}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
	&lt;p&gt;
	В таком случае следует сделать для главной страницы отдельный шаблон, в котором левой колонки нет:
	&lt;/p&gt;
	&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc0&quot;&gt;&amp;lt;!DOCTYPE HTML&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;/span&gt;...&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; {* + $/templates/header.tpl *} &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;&amp;lt;!-- а тут левой колонки нет --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;center-for-mainpage&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {* +&amp;gt; *content* *}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; {* + $/templates/footer.tpl *}&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
	&lt;p&gt;
	Сохраним этот шаблон, например, в файле  &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;mainpage/_page.tpl&lt;/span&gt; и укажем это в записи для главной страницы, заполнив поле &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;template&lt;/span&gt;:
	&lt;/p&gt;
	&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; pages &lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; url = &lt;span class=&quot;st0&quot;&gt;'/'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; template = &lt;span class=&quot;st0&quot;&gt;'$/mainpage/_page.tpl'&lt;/span&gt; ;&lt;/div&gt;
	&lt;p&gt;
	У остальных страниц поле &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;template&lt;/span&gt; будет пустым, и это послужит инструкцией использовать для них общий шаблон, указанный при создании объекта маршрутизатора — &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;$/templates/_page.tpl&lt;/span&gt;.
	&lt;/p&gt;
&lt;h2&gt;Постраничное подключение javascript- и css-файлов&lt;/h2&gt;
	&lt;p&gt;
	Помимо общих файлов, которые можно перечислить в секции &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; прямо в шаблоне, для отдельных страниц могут потребоваться специальные файлы. Чтобы обеспечить их подключение, нужно выполнить два действия:
	&lt;/p&gt;
	&lt;p&gt;
	1. Заполнить для страницы поле &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;headers&lt;/span&gt;, перечислив файлы через перевод строки. Например:
	&lt;/p&gt;
	&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; pages &lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; url = &lt;span class=&quot;st0&quot;&gt;'/'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; headers = &lt;span class=&quot;st0&quot;&gt;'/mainpage/style.css&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;http://code.jquery.com/jquery.min.js&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/mainpage/intro.js &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/mainpage/document-ready.js'&lt;/span&gt; ;&lt;/div&gt;
	&lt;p&gt;
	Пути к файлам будут вставлены в HTML-код страницы ровно в том виде, в котором они указаны.
	&lt;/p&gt;
	&lt;p&gt;
	При отсутствии расширения в адресе тип файла следует явно указать в начале:
	&lt;br&gt;
	&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;js https://api-maps.yandex.ru/2.1/?load=package.full&amp;amp;lang=ru-RU&lt;/span&gt;
	&lt;/p&gt;
	&lt;p&gt;
	2. Отредактировать шаблон страниц, поместив внутрь тега &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; следующую конструкцию:
	&lt;/p&gt;
	&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;{%*headers.css*} &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;link&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;rel&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{*headers.css:*}&amp;quot;&lt;/span&gt; /&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; {*headers.css*%}&lt;br /&gt;
{%*headers.js*} &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;script&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{*headers.js:*}&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/span&gt; {*headers.js*%}&lt;/div&gt;
	&lt;p&gt;
	В результате шаблон примет приблизительно такой вид:
	&lt;/p&gt;
	&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc0&quot;&gt;&amp;lt;!DOCTYPE HTML&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;&lt;/span&gt;{* + &amp;gt;*title* *}&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;description&amp;quot;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{* + &amp;gt;&lt;/span&gt;*description* *}&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&amp;lt;meta name=&amp;quot;&lt;/span&gt;keywords&lt;span class=&quot;st0&quot;&gt;&amp;quot; content=&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;* + &lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;*keywords* *}&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;&amp;lt;!-- тут можно без всяких условий подключить файлы, необходимые для всех страниц --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;link&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;rel&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;/css/common.css&amp;quot;&lt;/span&gt; /&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;script&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;/js/jquery.min.js&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;&amp;lt;!-- а вот указание на постраничные файлы: --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {%*headers.css*} &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;link&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;rel&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{*headers.css:*}&amp;quot;&lt;/span&gt; /&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; {*headers.css*%}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; {%*headers.js*} &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;script&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;{*headers.js:*}&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/span&gt; {*headers.js*%}&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ... &lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2&gt;Разделение однородного пространства адресов&lt;/h2&gt;
	&lt;p&gt;
	Встречаются случаи, когда разнородные сущности имеют одинаковые по виду адреса страниц.
	&lt;/p&gt;
	&lt;p&gt;
	Рассмотрим пример. Предположим, речь идет об интернет-магазине, где товары разбиты на категории, у каждой из которых должна быть своя страница с адресом вида &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/название категории&lt;/span&gt;. У каждого производителя товаров тоже должна быть своя страница с адресом вида &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/название производителя&lt;/span&gt;.
	&lt;/p&gt;
	&lt;p&gt;
	Оба этих случая описываются регулярным выражением &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/[^/]+&lt;/span&gt;&lt;sup&gt;&lt;a name=&quot;ftn-12&quot; href=&quot;#ftnref-12&quot;&gt;12&lt;/a&gt;&lt;/sup&gt;, которое не позволяет отличить один от другого. При этом составить более точные выражения, подходящие для каждого из этих случаев в отдельности, нельзя.&lt;sup&gt;&lt;a name=&quot;ftn-13&quot; href=&quot;#ftnref-13&quot;&gt;13&lt;/a&gt;&lt;/sup&gt;
	&lt;/p&gt;
	&lt;p&gt;
	В такой ситуации потребуется выполнить следующие действия.
	&lt;/p&gt;
	&lt;p&gt;
	Для начала нужно добавить в таблицу &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;pages&lt;/span&gt; запись, соответсвующую такому адресу, при этом снабдив её специальными инструкциями:
	&lt;/p&gt;
	&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; pages &lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; url = &lt;span class=&quot;st0&quot;&gt;'/[^/]+'&lt;/span&gt;, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; code = &lt;span class=&quot;st0&quot;&gt;'Categories-&amp;gt;getData(1) &amp;nbsp; &amp;nbsp;[cat] &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;category&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Manufacturers-&amp;gt;getData(1) [manufacturer] manufacturer'&lt;/span&gt; ;&lt;/div&gt;
	&lt;p&gt;
	Формально эта запись является страницей, но фактически она представляет собой &amp;laquo;развилку&amp;raquo;&lt;sup&gt;&lt;a name=&quot;ftn-14&quot; href=&quot;#ftnref-14&quot;&gt;14&lt;/a&gt;&lt;/sup&gt;, от которой идут две &amp;laquo;дорожки&amp;raquo; — к категориям (&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;category&lt;/span&gt;) и к производителям (&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;manufacturer&lt;/span&gt;).
	&lt;/p&gt;
	&lt;p&gt;
	Разберем эти инструкции подробнее.
	&lt;/p&gt;
	&lt;p&gt;
	Вспомним инструкцию &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Posts-&amp;gt;getData() [post] $/posts/single.php&lt;/span&gt;, которая предписывала проверить адрес и в случае успеха записать данные в &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;pageData&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'post'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/span&gt;, передав затем управление файлу &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;posts/single.php&lt;/span&gt;.
	&lt;/p&gt;
	&lt;p&gt;
	Похожим образом действует и инструкция &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Categories-&amp;gt;getData(1) [cat] category&lt;/span&gt;, однако в третьей ее части стоит не путь к PHP-файлу, а указатель на другую запись в таблице &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;pages&lt;/span&gt;&lt;sup&gt;&lt;a name=&quot;ftn-15&quot; href=&quot;#ftnref-15&quot;&gt;15&lt;/a&gt;,&lt;a name=&quot;ftn-16&quot; href=&quot;#ftnref-16&quot;&gt;16&lt;/a&gt;&lt;/sup&gt;, которой и будет передано управление. Этот указатель представляет собой значение поля &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;url&lt;/span&gt; целевой записи.
	&lt;/p&gt;
	&lt;p&gt;
	Вот как примерно выглядит эта запись:
	&lt;/p&gt;
	&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; pages &lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; url = &lt;span class=&quot;st0&quot;&gt;'category'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; title = &lt;span class=&quot;st0&quot;&gt;'{*cat.title*}'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; description = &lt;span class=&quot;st0&quot;&gt;'{*cat.description*}'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; keywords = &lt;span class=&quot;st0&quot;&gt;'...'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; content = &lt;span class=&quot;st0&quot;&gt;'&amp;lt;h1&amp;gt;{*cat.title*}&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; '&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; code = &lt;span class=&quot;st0&quot;&gt;'(здесь можно пользоваться $this-&amp;gt;pageData[cat])'&lt;/span&gt;;&lt;/div&gt;
	&lt;p&gt;
	Это обычная страница&lt;sup&gt;&lt;a name=&quot;ftn-17&quot; href=&quot;#ftnref-17&quot;&gt;17&lt;/a&gt;&lt;/sup&gt;, которой уже доступны данные категории в &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;pageData&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'cat'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/span&gt;. Они используются в полях страницы в виде переменных &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;{*cat.ключ*}&lt;/span&gt; и, при необходимости, могут быть задействованы в назначенном ей PHP-коде.
	&lt;/p&gt;
	&lt;p&gt;
	Если проверка адреса с помощью &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Categories-&amp;gt;&lt;span class=&quot;me1&quot;&gt;getData&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; потерпела неудачу, маршрутизатор немедленно переходит к следующей инструкции —
	&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Manufacturers-&amp;gt;getData(1) [manufacturer] &amp;nbsp;manufacturer&lt;/span&gt; (которой соответствует страница с &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;url = &lt;span class=&quot;st0&quot;&gt;'manufacturer'&lt;/span&gt;&lt;/span&gt;) и так далее до тех пор, пока проверка адреса не завершится успешно или не закончатся инструкции. В последнем случае код HTTP-ответа будет установлен маршрутизатором в &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;404&lt;/span&gt;.
	&lt;/p&gt;
&lt;h2&gt;Выделение подпространства адресов&lt;/h2&gt;
	&lt;p&gt;
	Бывает, что адреса некоторой группы страниц попадают в другую, более широкую, группу.
	&lt;/p&gt;
	&lt;p&gt;
	Допустим, имеется интернет-магазин, в котором страницы товаров имеют адреса вида &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/производитель/модель.html&lt;/span&gt;, а страницы точек розничной продажи — &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/shops/(id точки).html&lt;/span&gt;. Первые при этом описываются регулярным выражением &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/[^/]+/[^/]+\.html&lt;/span&gt;, а вторые —  &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/shops/\d+\.html&lt;/span&gt;. Тогда адрес страницы конкретной розничной точки, например &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/shops/1.html&lt;/span&gt;, совпадет с обоими выражениями.
	&lt;/p&gt;
	&lt;p&gt;
	В таком случае маршрутизатору нужно сообщить, что более строгое выражение должно обрабатываться первым. Для этого его нужно предварить числом. Например:&lt;br&gt; &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;10 /shops/\d+\.html&lt;/span&gt;.
	Это число маршрутизатор рассматривает как приоритет, обрабатывая первыми страницы с б&amp;#x301;ольшим приоритетом.&lt;sup&gt;&lt;a name=&quot;ftn-18&quot; href=&quot;#ftnref-18&quot;&gt;18&lt;/a&gt;&lt;/sup&gt;
	&lt;/p&gt;
	&lt;p&gt;
	Аналогичного эффекта можно достичь, если менее строгому выражению указать отрицательный приоритет — &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;-10 /[^/]+/[^/]+&lt;/span&gt;, а более строгое оставить без изменений.
	&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;_404&quot;&gt;&lt;/a&gt;Ошибка 404&lt;/h2&gt;
	&lt;p&gt;
		Маршрутизатор считает, что запрошенная страница не существует на сайте, в следующих случаях:
	&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;не обнаружена запись в таблице &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;pages&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;проверка всех инструкций &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Класс-&amp;gt;метод() [ключ] указатель&lt;/span&gt; закончилась неудачей&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;
		В такой ситуации маршрутизатор установит HTTP-код ответа в &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;404&lt;/span&gt;.
	&lt;/p&gt;
	&lt;p&gt;
		Можно создать специальную страницу, которую маршрутизатор автоматически будет отдавать в таких случаях&lt;sup&gt;&lt;a name=&quot;ftn-19&quot; href=&quot;#ftnref-19&quot;&gt;19&lt;/a&gt;&lt;/sup&gt;. Её &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;url&lt;/span&gt; должен быть равным &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'404'&lt;/span&gt;&lt;/span&gt;:
	&lt;/p&gt;
	&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; pages &lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; url = &lt;span class=&quot;st0&quot;&gt;'404'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; title = &lt;span class=&quot;st0&quot;&gt;'Ошибка 404 - страница не найдена.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; content = &lt;span class=&quot;st0&quot;&gt;'&amp;lt;h1&amp;gt;Ошибка: страница не найдена&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;p&amp;gt;Страницы с адресом {*$_SERVER.REQUEST_URI*} на сайте нет.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;!-- в шаблонах можно использовать суперглобальные переменные --&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; '&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp;code = &lt;span class=&quot;st0&quot;&gt;'(и в этом случае тоже можно назначать исполняемый код)'&lt;/span&gt;;&lt;/div&gt;
&lt;h2&gt;&lt;a name=&quot;ajax&quot;&gt;&lt;/a&gt;Об адресах для AJAX-запросов&lt;/h2&gt;
	&lt;p&gt;
	Ответы на AJAX-запросы не являются полноценными страницами сайта, поэтому включать их в общее виртуальное пространство адресов под управлением маршрутизатора не рекомендуется.
	&lt;/p&gt;
	&lt;p&gt;
	Следует принять соглашение, по которому адреса таких запросов содержат некоторый фрагмент (например, &amp;quot;ajax&amp;quot;), дополнив соответствующим образом настройки веб-серверов.
	&lt;/p&gt;
	&lt;h3&gt;Apache&lt;/h3&gt;
	&lt;p&gt;
	Нужная директива записывается так: &lt;span class=&quot;code apache&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;RewriteCond&lt;/span&gt; %&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;REQUEST_URI&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; !ajax&lt;/span&gt;. Весь набор директив примет вид&lt;sup&gt;&lt;a name=&quot;ftn-20&quot; href=&quot;#ftnref-20&quot;&gt;20&lt;/a&gt;&lt;/sup&gt;:
	&lt;/p&gt;
	&lt;div class=&quot;code apache&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;RewriteEngine&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;on&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;RewriteCond&lt;/span&gt; %&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;REQUEST_FILENAME&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; !-f &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;OR&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;RewriteCond&lt;/span&gt; %&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;REQUEST_FILENAME&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; \.php$&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;RewriteCond&lt;/span&gt; %&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;REQUEST_URI&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; !ajax&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;RewriteRule&lt;/span&gt; .* _showpage.php&lt;/div&gt;
	&lt;h3&gt;nginx&lt;/h3&gt;&lt;/p&gt;
	&lt;p&gt;
	Директиву &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;location&lt;/span&gt; для &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;*.php&lt;/span&gt; потребуется дополнить, и она примет вот такой вид:
	&lt;/p&gt;
	&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;location ~ \.php$ {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if ($uri !~ ajax) {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 404;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&amp;nbsp; &amp;nbsp; fastcgi_pass $php_socket; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; fastcgi_param SCRIPT_FILENAME $document_root$uri;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; include fastcgi_params;&lt;br /&gt;
}&lt;/div&gt;
&lt;div class=&quot;footnote&quot;&gt;
	&lt;p&gt;1.&lt;a name=&quot;ftnref-1&quot; href=&quot;#ftn-1&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
		Подробнее об использовании mod_rewrite и .htaccess можно прочитать &lt;a href=&quot;http://webew.ru/articles/2291.webew&quot; title=&quot;Централизация обработки запросов к сайту с помощью mod_rewrite&quot;&gt;в этой немного устаревшей статье&lt;/a&gt;.
	&lt;/p&gt;
	&lt;p&gt;2.&lt;a name=&quot;ftnref-2&quot; href=&quot;#ftn-2&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
		Директива &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;RewriteCond %{REQUEST_FILENAME} \.php$&lt;/span&gt; воспрепятствует исполнению файлов &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;*.php&lt;/span&gt; в ответ на прямой запрос через веб-сервер.
	&lt;/p&gt;
	&lt;p&gt;3.&lt;a name=&quot;ftnref-3&quot; href=&quot;#ftn-3&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
		Менее строгим, но и менее ресурсоемким (засчет отсутствия проверки существования физического файла) является явное перечисление фрагментов имен файлов (обычно расширений), встречая которые, веб-серверу не следует задействовать PHP:
		&lt;div class=&quot;code apache&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;RewriteEngine&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;on&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;RewriteCond&lt;/span&gt; %&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;REQUEST_FILENAME&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; !\.&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;css|js|png|jpg|gif&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;$&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;RewriteRule&lt;/span&gt; .* _showpage.php&lt;/div&gt;
	&lt;/p&gt;
	&lt;p&gt;4.&lt;a name=&quot;ftnref-4&quot; href=&quot;#ftn-4&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
		При желании можно поместить содержимое страницы во вложенный шаблон полностью. Например:
		&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; pages &lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; url = &lt;span class=&quot;st0&quot;&gt;'/'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; content = &lt;span class=&quot;st0&quot;&gt;'{* + $/mainpage/content.tpl *}'&lt;/span&gt;;&lt;/div&gt;
	&lt;/p&gt;
	&lt;p&gt;5.&lt;a name=&quot;ftnref-5&quot; href=&quot;#ftn-5&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
		В том числе инструкция вида &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;{* + &amp;gt;*имя* *}&lt;/span&gt;, предписывающая не просто подставить значение переменной, но еще и обработать само это значение как шаблона: искать в содержимом переменной ссылки на другие переменные, а также все остальные синтаксические выражения обычных шаблонов. Именно использование таких инструкций (&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;{* + &amp;gt;*title* *}&lt;/span&gt;, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;{* + &amp;gt;*content* *}&lt;/span&gt; и т.п.) в общих шаблонах для страниц обеспечивает динамическую обработку полей &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;title&lt;/span&gt;, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;description&lt;/span&gt;, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;keywords&lt;/span&gt; и &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;content&lt;/span&gt;.
	&lt;/p&gt;
	&lt;p&gt;6.&lt;a name=&quot;ftnref-6&quot; href=&quot;#ftn-6&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
		Вообще говоря, в связке с маршрутизатором может быть использован любой  схожий по возможностям с &lt;a href=&quot;http://webew.ru/articles/3609.webew&quot;&gt;websun&lt;/a&gt; обработчик шаблонов. Websun является вариантом, к использованию рекомендуемым, но не обязательным. Никаких специальных взаимных требований друг к другу маршрутизатор и обработчик не имеют.
	&lt;/p&gt;
	&lt;p&gt;7.&lt;a name=&quot;ftnref-7&quot; href=&quot;#ftn-7&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Сокращение &amp;quot$&amp;quot, как и в случае путей к шаблонам, обозначает корневой каталог веб-сервера.
	&lt;/p&gt;
	&lt;p&gt;8.&lt;a name=&quot;ftnref-8&quot; href=&quot;#ftn-8&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Технически файл подключается внутри одного из методов маршрутизатора, поэтому код файла выполняется в контексте объекта.
	&lt;/p&gt;
	&lt;p&gt;9.&lt;a name=&quot;ftnref-9&quot; href=&quot;#ftn-9&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
		Нотация с точкой соответствует в языке шаблонизатора следующему уровню вложенности массива: &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;{*post.title*}&lt;/span&gt; — &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;pageData&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'post'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;{*post.date*}&lt;/span&gt; — &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;pageData&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'post'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'date'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/span&gt; и т.п.
	&lt;/p&gt;
	&lt;p&gt;10.&lt;a name=&quot;ftnref-10&quot; href=&quot;#ftn-10&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
		Механизм маршрутизатора автоматически добавляет символы начала и конца строки перед анализом пути, т.е. запись &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/posts/(\d+).html&lt;/span&gt; на самом деле приведет к сопоставлению с выражением &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;^/posts/(\d+).html$&lt;/span&gt;. Поэтому ошибочное совпадение с частью пути запроса (например, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/something/posts/13.html&lt;/span&gt; или &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/posts/13.html/something&lt;/span&gt;) исключено.
		&lt;br&gt;
		Сопоставление проводится в режиме регистронезависимости (флаг &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;i&lt;/span&gt;).
	&lt;/p&gt;
	&lt;p&gt;11.&lt;a name=&quot;ftnref-11&quot; href=&quot;#ftn-11&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
		Запись &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Posts-&amp;gt;getData(1) [post] $/posts/single.php&lt;/span&gt; в &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;code&lt;/span&gt; страницы равносильна следующей:
		&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;?php&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// Код будет выполняться только в случае успешного сопоставления&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// пути запроса регулярному выражению; при этом маршрутизатор &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// записывает массив с результатами этого сопоставления в свойство matches.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$Obj&lt;/span&gt; = &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; Posts;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$data&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$Obj&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;getData&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; http_response_code&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;pageData&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'post'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$data&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;$_SERVER[DOCUMENT_ROOT]/posts/single.php&amp;quot;&lt;/span&gt;; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// а точнее - $this-&amp;gt;requireFile('$/posts/single.php');&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; http_response_code&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;404&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw2&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/div&gt;
	Аналог для &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Posts-&amp;gt;getData(1) [post]&lt;/span&gt;, очевидно, выглядит так же, за исключением отсутствия &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;require&lt;/span&gt; файла.&lt;/p&gt;
	&lt;p&gt;12.&lt;a name=&quot;ftnref-12&quot; href=&quot;#ftn-12&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Круглые скобки нужны в данном случае лишь для того, чтобы дать маршрутизатору указание рассматривать адрес этой страницы как динамический и использовать его в качестве регулярного выражения, а не для простой проверки на равенство (как это делается для страниц со статическим адресом).
	&lt;/p&gt;
	&lt;p&gt;13.&lt;a name=&quot;ftnref-13&quot; href=&quot;#ftn-13&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	В подобных случаях из положения обычно выходят, выделяя каждому роду сущностей свое подпространство, что приводит к адресам вида &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/cat/категория&lt;/span&gt; вместо &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;/категория&lt;/span&gt;. Такое решение, как правило, обсуловлено именно техническими ограничениями механизма сайта, поскольку более короткие и наглядные адреса обычно являются более предпочтительными.
	&lt;/p&gt;
	&lt;p&gt;14.&lt;a name=&quot;ftnref-14&quot; href=&quot;#ftn-14&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Именно поэтому у неё не указаны никакие поля, кроме &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;url&lt;/span&gt; и &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;code&lt;/span&gt;.
	&lt;/p&gt;
	&lt;p&gt;15.&lt;a name=&quot;ftnref-15&quot; href=&quot;#ftn-15&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Если третья часть инструкции заканчивается фрагментом &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;.php&lt;/span&gt;, она считается путем к PHP-файлу, в противном случае — указателем на страницу.
	&lt;/p&gt;
	&lt;p&gt;16.&lt;a name=&quot;ftnref-16&quot; href=&quot;#ftn-16&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	В случае, если указатель ссылается на несуществующую запись, маршрутизатор будет считать, что страница с запрошенным адресом не существует. Подробнее см. &lt;a href=&quot;#_404&quot;&gt;соответствующий раздел статьи&lt;/a&gt;.
	&lt;/p&gt;
	&lt;p&gt;17.&lt;a name=&quot;ftnref-17&quot; href=&quot;#ftn-17&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Нужно сказать, однако, что доступ к этой странице напрямую невозможен в принципе: любой адрес начинается со слэша, а здесь в поле &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;url&lt;/span&gt; ведущего слэша нет. Потому такая страница может быть задействована только через описанное указание-&amp;laquo;развилку&amp;raquo;.
	&lt;/p&gt;
	&lt;p&gt;18.&lt;a name=&quot;ftnref-18&quot; href=&quot;#ftn-18&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Число-приоритет должно быть целым. Его можно отделять от регулярного выражения пробелом — для удобочитаемости.
	&lt;/p&gt;
	&lt;p&gt;19.&lt;a name=&quot;ftnref-19&quot; href=&quot;#ftn-19&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Если специальную страницу не заводить, то маршрутизатор все равно будет отдавать код &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;404&lt;/span&gt;, но пользователь увидит либо пустой экран, либо результат замены меток для подстановки данных в основном шаблоне на пустые строки.
	&lt;/p&gt;
	&lt;p&gt;20.&lt;a name=&quot;ftnref-20&quot; href=&quot;#ftn-20&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Или
	&lt;div class=&quot;code apache&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;RewriteEngine&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;on&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;RewriteCond&lt;/span&gt; %&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;REQUEST_FILENAME&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; !\.&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;css|js|png|jpg|gif&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;$&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;RewriteCond&lt;/span&gt; %&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;REQUEST_URI&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; !ajax&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;RewriteRule&lt;/span&gt; .* _showpage.php&lt;/div&gt;
	для менее ресурсоемкой конфигурации, &lt;a href=&quot;#ftnref-3&quot;&gt;упоминавшейся ранее&lt;/a&gt;.
	&lt;/p&gt;
&lt;/div&gt;
</description>
</item>
<item>
  <title></title>
  <link>http://webew.ru/posts/5157.webew#5188</link>
  <guid>http://webew.ru/posts/5157.webew#5188</guid>
  <pubDate>Thu, 17 Apr 2014 16:33:51 +0400</pubDate>
  <description>Всего неделя остается до РИТ++ 2014 в Санкт-Петербурге, &lt;a href=&quot;http://ritconf.ru/2014/abstracts?city=spb&quot;&gt;программа&lt;/a&gt; которой &lt;span class=&quot;b&quot;&gt;значительно отличается от московского варианта&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Вот что об этом говорят сами организаторы:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;quotetitle&quot;&gt;Цитата:&lt;/div&gt;&lt;div class=&quot;quote&quot;&gt;Новость первая - оказывается программа в Санкт-Петербурге очень сильна и довольно серьёзно расходится с Московской. Вот, например, список ключевых на наш взгляд, докладов:&lt;br /&gt;
&lt;br /&gt;
    Как мы сделали IDE для HTML5 на HTML5 / Константин Лихтер (Intel Corporation)&lt;br /&gt;
    Сравнение современных систем управления конфигурацией Chef, Puppet, Salt, Ansible / Житинский Сергей Александрович (Git in Sky);&lt;br /&gt;
    Технический долг. Сколько мы должны и как заплатить по счетам? / Павлов Дмитрий Юрьевич (Smart Step Group);&lt;br /&gt;
    Архитектура AVITO.ru / Роман Павлушко (AVITO.ru);&lt;br /&gt;
    Как вырастить команду хороших веб-технологов / Нарек Мкртчян (Quins);&lt;br /&gt;
    Архитектура и оптимизация большого одностраничного AngularJS-приложения / Антон Плешивцев (Aviasales.ru);&lt;br /&gt;
    7 принципов разработки собственных key/value решений или 500М счетчиков ещё не предел на примере SophiaDb / Календарев Александр Михайлович (loveplanet.ru);&lt;br /&gt;
    Защищённое хранение данных и проведение операций в облачных БД / Владислав Андреевич Бойко (Parallels).&lt;br /&gt;
&lt;br /&gt;
Роман из Avito.RUТут и высоконагруженные системы и базы данных (другие), облачные вычисления (тоже другие). Есть несколько докладов, которые вообще не звучали в Москве. Например, &amp;quot;Архитектура AVITO.ru&amp;quot; от Романа Павлушко.&lt;br /&gt;
&lt;br /&gt;
В докладе поговорим о high-level архитектуре проекта AVITO.ru.  Что такое AVITO.ru в цифрах:&lt;br /&gt;
&lt;br /&gt;
    сотни миллионов динамических запросов в сутки&lt;br /&gt;
    десятки терабайт статических данных&lt;br /&gt;
    терабайтные базы данных&lt;br /&gt;
    тысячи rps на поисковой кластер&lt;br /&gt;
    десятки гигабайт clickstream-данных в день&lt;br /&gt;
    миллиарды счетчиков&lt;br /&gt;
    более 100 достаточно мощных серверов&lt;br /&gt;
&lt;br /&gt;
Чтобы переваривать указанные выше потоки данных и вычислений, но при этом не терять темпы разработки и поддержки продукта, мы постоянно расширяем технологический стек. В настоящее время мы уже плотно сидим на таких продуктах как: nginx, PHP, PostgreSQL, Sphinx, redis, mongodb и пр. Каждый продукт для нас - это оптимальное решение задач разработки и экономии серверных ресурсов.&lt;/div&gt;</description>
</item>
<item>
  <title></title>
  <link>http://webew.ru/posts/5157.webew#5172</link>
  <guid>http://webew.ru/posts/5157.webew#5172</guid>
  <pubDate>Fri, 04 Apr 2014 17:32:49 +0400</pubDate>
  <description>Как и всегда, цена на участие в конференции возрастает с приближением открытия.&lt;br /&gt;
До очередного &lt;span class=&quot;b&quot;&gt;повышения остается всего 3 дня — спешите!&lt;/span&gt;</description>
</item>
<item>
  <title>РИТ 2014++ (скидка внутри!)</title>
  <link>http://webew.ru/posts/5157.webew</link>
  <guid>http://webew.ru/posts/5157.webew</guid>
  <pubDate>Tue, 11 Mar 2014 15:23:27 +0400</pubDate>
  <description>Очередная ежегодная &lt;a href=&quot;http://ritconf.ru&quot;&gt;конференция веб-разработчиков Российские Интернет-Технологии 2014&lt;/a&gt; будет проходить в апреле этого года, на этот раз не только в Москве (14-15 апреля), но и в Санкт-Петербурге (24-25 апреля).&lt;br /&gt;
&lt;br /&gt;
С приближением конференции цена возрастает, поэтому регистрироваться на нее лучше заранее. &lt;br /&gt;
Аудитории webew.ru предоставляется &lt;span class=&quot;b&quot;&gt;специальная скидка 10%&lt;/span&gt;, которая доступна по промо-коду &lt;span class=&quot;b&quot;&gt;sql_friends&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Подробнее о программе конференции:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;quotetitle&quot;&gt;Цитата:&lt;/div&gt;&lt;div class=&quot;quote&quot;&gt;Прошла первая встреча докладчиков и Программного комитета, нам набросали пять экранов пожеланий. Тут и доклад от Константина Осипова по обновлённому Tarantool (он успел его переписать), и доклад от Максима Лапшина по базам данных (включая собственную разработку) для хранения временных рядов. Пара относительно новых баз данных (Tiger) и свежие версии промышленных стандартов (PostgreSQL 9.3).&lt;br /&gt;
&lt;br /&gt;
Возобновился интерес слушателей к системам виртуализации и появился к новым принципам и концепциям в построении систем хранения и СУБД - например WriteOnly или OnlySSD. Приз, без сомнения, заслуживает Сергей Аверин с запросом на доклад &amp;quot;Развитие криптовалют в криптостойкие распределённые системы хранения&amp;quot; :) Что ж, попробуем найти.&lt;br /&gt;
&lt;br /&gt;
По серверному программированию интересы слушателей касаются новых языков программирования, фреймворков и концепций ускорения PHP (компиляция PHP в байт-код или компиляция ограниченного набора инструкций PHP в код на C).&lt;br /&gt;
&lt;br /&gt;
По архитектурам и высоконагруженным проектам нам интересны мессенджеры, включая Telegram (поедем на поклон к Николаю Дурову), интересна Олимпиада в Сочи (в России всего два сайта, использующих Olympic Data Feed - количество информации, которую можно найти на сайте sochi2014.com просто колоссально - вплоть до конкретных оценок для конкретных фигуристов за конкретные прыжки или элементы).&lt;br /&gt;
&lt;br /&gt;
Мобильные разработки - здесь аудитория мечтает о фреймворке - ты на нём пишешь, а дальше все само :)&lt;br /&gt;
&lt;br /&gt;
Системное администрирование - опять виртуализация, отказоустойчивость и безопасность, но на этот раз на самом стандартном железе. Устройство интернет и что делать, если упадёт железный занавес. Приз за оригинальность получает заявка на доклад &amp;quot;Как пакистанский админ может отрубить YouTube?&amp;quot;. Опять Сочи 2014 - вопреки всем прогнозам, видеотрансляции из Сочи прекрасно работают и Российский интернет тоже. Да, у нас есть специальный отдел, который занимается тем, что уговаривает Игоря Сысоева выступить у нас. Надеемся на то, что заграница (зачёркнуто) Максим Дунин нам поможет :)&lt;br /&gt;
&lt;br /&gt;
Клиентские технологии - заявки по новым фреймворкам, включая фреймворки по HTML и по CSS (оказывается, есть и такие), тестирование JavaScript-кода, визуализация графиков, а также более глубокое изучение последствий перехода на Single Page Application и толстые клиенты. Например, одно из таких последствий - быстрый расход батарейки и такие монстры, как Facebook, уже начинают откат назад, отказ от лишней интерактивности и переход на более простые фреймворки.&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Есть также интересное предложение по Highload++ -  полный комплект материалов за все время проведения конференции, в который входят:&lt;br /&gt;
&lt;br /&gt;
- Видеозаписи всех докладов с 2007 по 2013 года&lt;br /&gt;
- Видеозапись учебного дня 2013 года&lt;br /&gt;
- Все презентации всех лет&lt;br /&gt;
- Расшифровка лучших докладов&lt;br /&gt;
- Одна PDF и одна бумажная книга с лучшими докладами&lt;br /&gt;
&lt;br /&gt;
Приобрести комплект можно по адресу &lt;a href=&quot;http://conf.ontico.ru/7years/&quot;&gt;http://conf.ontico.ru/7years/&lt;/a&gt;&lt;br /&gt;
Стоимость комплекта составляет 25000 руб. На комплект также действует скидка (см. в начале сообщения), поэтому для нашей аудитории он обойдется в 22500 руб.</description>
</item>
<item>
  <title>Легкий ORM для PHP и MySQL</title>
  <link>http://webew.ru/articles/5096.webew</link>
  <guid>http://webew.ru/articles/5096.webew</guid>
  <pubDate>Tue, 31 Dec 2013 00:28:53 +0400</pubDate>
  <description>&lt;!--h1&gt;Легкий ORM для PHP и MySQL&lt;/h1--&gt;
&lt;script&gt;var CONTENTS_LEVEL = [2,3];&lt;/script&gt;
&lt;p style=&quot;padding: 1em; border: 1px dotted; &quot;&gt;
    &lt;b&gt;21.12.2025&lt;/b&gt;: Продолжение разработки тут -
    &lt;a href=&quot;https://github.com/1234ru/listfromdb&quot;&gt;github.com/1234ru/listformdb&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
В статье приводится реализация объектно-реляционного отображения, выполненная в виде небольшой библиотеки с простым и гибким интерфейсом.
Код библиотеки доступен в виде &lt;a href=&quot;http://webew.ru/f/DcpQfkL3.php&quot;&gt;одного php-файла&lt;/a&gt;. В качестве интерфейса к базе данных используются &lt;a href=&quot;http://webew.ru/articles/3237.webew#download&quot;&gt;удобные функции PHP для работы с MySQL&lt;/a&gt;.
&lt;/p&gt;
&lt;!--&lt;h2&gt;Проблематика&lt;/h2&gt;--&gt;
&lt;p&gt;
Объектно-реляционное отображение (&lt;i&gt;англ.&lt;/i&gt; object-relational mapping или ORM) — техника программирования, которая позволяет разработчику абстрагироваться от механизмов работы хранилища данных и писать код в терминах логики конкретного приложения. В частности, заменять написание SQL-запросов вызовом специальных функций/методов.&lt;sup&gt;&lt;a name=&quot;ftnref-1&quot; href=&quot;#ftn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
&lt;/p&gt;
&lt;h2&gt;Поиск по параметрам&lt;/h2&gt;
&lt;p&gt;
Самая частая задача при разработке веб-приложений — это построение списка на основании некоторых условий. Такой список может быть разбит на страницы и определенным образом отсортирован.
&lt;/p&gt;
&lt;p&gt;
В качестве примера рассмотрим получение списка товаров для страницы каталога в интернет-магазине, относящейся к определенному производителю.
&lt;/p&gt;
&lt;p&gt;
Предположим, товары хранятся вот в такой таблице:
&lt;/p&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;mysql&amp;gt; SELECT * FROM products;&lt;br /&gt;
+----+-----------+-------+----------+-----------------+-------+&lt;br /&gt;
| id | title &amp;nbsp; &amp;nbsp; | price | discount | manufacturer_id | text &amp;nbsp;|&lt;br /&gt;
+----+-----------+-------+----------+-----------------+-------&lt;br /&gt;
| &amp;nbsp;1 | Веник &amp;nbsp; &amp;nbsp; | &amp;nbsp; 100 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1 | &amp;nbsp; &amp;nbsp; &amp;nbsp; |&lt;br /&gt;
| &amp;nbsp;2 | Швабра &amp;nbsp; &amp;nbsp;| &amp;nbsp; 500 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1 | &amp;nbsp; &amp;nbsp; &amp;nbsp; |&lt;br /&gt;
| &amp;nbsp;3 | Чайник &amp;nbsp; &amp;nbsp;| &amp;nbsp;1500 | &amp;nbsp; &amp;nbsp; &amp;nbsp; 10 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 2 | &amp;nbsp; &amp;nbsp; &amp;nbsp; |&lt;br /&gt;
| &amp;nbsp;4 | Совок &amp;nbsp; &amp;nbsp; | &amp;nbsp; 150 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1 | &amp;nbsp; &amp;nbsp; &amp;nbsp; |&lt;br /&gt;
| &amp;nbsp;5 | Телевизор | &amp;nbsp;5000 | &amp;nbsp; &amp;nbsp; &amp;nbsp; 30 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 3 | &amp;nbsp; &amp;nbsp; &amp;nbsp; |&lt;br /&gt;
| &amp;nbsp;6 | Ведро &amp;nbsp; &amp;nbsp; | &amp;nbsp; 200 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0 | &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1 | &amp;nbsp; &amp;nbsp; &amp;nbsp; |&lt;br /&gt;
+----+-----------+-------+----------+-----------------+-------+&lt;/div&gt;
&lt;p&gt;
Страница каталога снабжена формой поиска, позволяющей ограничивать список товаров по некоторым параметрам:
&lt;/p&gt;
&lt;style&gt;
	form.example {
		display: inline-block;
		line-height: 2.5em;
		}
		form.example input, form.example select { height: 1.5em; font-size: inherit; }
		form.example select { display: inline-block; width: 112px; }
		form.example input[type=checkbox] {
			vertical-align: middle;
			margin-left: 1em;
			width: auto;
			}
		form.example input[name^=price] { width: 4em; }
		form.example input[name^=title] { width: 12em; }
&lt;/style&gt;
&lt;form class=&quot;example&quot;&gt;
	Цена от &lt;input name=&quot;price_final[min]&quot;&gt;
	     до &lt;input name=&quot;price_final[max]&quot;&gt;
	&lt;input name=&quot;has_discount&quot; type=&quot;checkbox&quot;&gt; скидка
	&lt;button&gt;OK&lt;/button&gt;
	&lt;br&gt;
	Название (начинается с) &lt;input name=&quot;title&quot;&gt;
&lt;/form&gt;
&lt;p&gt;
HTML-код формы:
&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;form&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;id&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;example&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Цена от &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;price_final[min]&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; до &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;price_final[max]&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;has_discount&amp;quot;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; скидка&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;button&amp;gt;&lt;/span&gt;&lt;/span&gt;OK&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;br&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Название (начинается с) &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
В этом случае код, необходимый для получения данных товаров, будет выглядеть следующим образом:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'ORM.php'&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;manufacturer_id = 2&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'where'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'orderby'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'[ord]'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'limit'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;, &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'N'&lt;/span&gt;,&lt;span class=&quot;nu0&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt; = &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; Products;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$products&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Методу &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;find&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; передается массив с условиями поиска: конкретные значения параметров, указания по сортировке и LIMIT, а также ограничения выборки, задаваемые вручную.
&lt;p&gt;
&lt;/p&gt;
Ключ &lt;i&gt;where&lt;/i&gt; этого массива содержит значения параметров поиска, из которых по определенным правилам формируются условия конечного SQL-запроса (см. &lt;a href=&quot;#search-params&quot;&gt;конфигурация параметров поиска&lt;/a&gt;). При вставке в запрос значения параметров автоматически экранируются&lt;sup&gt;&lt;a name=&quot;ftnref-2&quot; href=&quot;#ftn-2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;, лишние ключи (для которых в конфигурации нет соответствующего параметра) просто игнорируются.
&lt;/p&gt;
&lt;p&gt;
Остальные условия поиска будут подробно рассмотрены в соответствующих разделах статьи (&lt;a href=&quot;#explicit-where&quot;&gt;произвольные условия&lt;/a&gt;, &lt;a href=&quot;#limit&quot;&gt;LIMIT&lt;/a&gt;, &lt;a href=&quot;#orderby&quot;&gt;сортировка&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
Класс Products унаследован от специального абстрактного класса библиотеки и содержит в своем определении отображение параметров поиска (читай — полей формы) на структуру базы данных:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;Class&lt;/span&gt; Products &lt;span class=&quot;kw2&quot;&gt;extends&lt;/span&gt; _List &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$tables&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;FROM products p&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// здесь могут быть также JOIN с другими таблицами&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'id'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'price_final'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'sql'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;price * (100 - discount) / 100&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'type'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'[min,max]'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'type'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'LIKE%'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'has_discount'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'sql'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;discount &amp;gt; 0&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'type'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'on-off'&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Чтобы вместо полных данных строк получить только их идентификаторы, нужно воспользоваться
методом &lt;strong&gt;findIds()&lt;/strong&gt;, интерфейс которого полностью аналогичен таковому метода
&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;find&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$product_ids&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;findIds&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$count&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Для получения полных данных списка на основе уникальных идентификаторов служит метод &lt;strong&gt;getList()&lt;/strong&gt;:&lt;sup&gt;&lt;a name=&quot;ftnref-9&quot; href=&quot;#ftn-9&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$products&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;getList&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$product_ids&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// $product_ids внутри метода будут проэкранированы&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Идентификатор одиночной сущности можно получить с помощью метода &lt;strong&gt;findId()&lt;/strong&gt;:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$product_id&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;findId&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;h3&gt;&lt;a name=&quot;search-params&quot;&gt;&lt;/a&gt;Конфигурация параметров поиска&lt;/h3&gt;
&lt;p&gt;
Теперь обратимся к массиву $columns и рассмотрим конфигурацию каждого из полей детально.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Поле, являющееся уникальным идентификатором записи в главной таблице, обязательно должно присутствовать и следовать в списке первым.&lt;/strong&gt; Именно поэтому id упоминается в конфигурационном массиве, хотя его нет в форме.
&lt;/p&gt;
&lt;p&gt;
Ключ &lt;i&gt;type&lt;/i&gt; определяет, как конкретно указанное SQL-выражение будет сопоставлено значению соответствующего параметра (эти значения входят в условия для построения списка (массив $query) и передаются в ключе &lt;i&gt;where&lt;/i&gt;). Сопоставление бывает четырех видов.
&lt;/p&gt;
&lt;h4&gt;Равенство&lt;/h4&gt;
&lt;p&gt;
&lt;i&gt;type&lt;/i&gt;, не установленный вовсе (как в случае с id) или равный FALSE в результате даст условие со знаком &amp;laquo;равно&amp;raquo;, а если значения параметра является не скалярной величиной, а массивом, то IN.
&lt;/p&gt;
&lt;p&gt;
Например, если бы $_GET содержал в ключе id число 10, получилось бы условие
&lt;/p&gt;
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;p.id = &lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
а если бы — массив &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;Атос&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;&amp;quot;Д'Артаньян&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;, то&lt;sup&gt;&lt;a name=&quot;ftnref-3&quot; href=&quot;#ftn-3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
&lt;/p&gt;
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;p.id &lt;span class=&quot;kw1&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'Атос'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'Д&lt;span class=&quot;es0&quot;&gt;\'&lt;/span&gt;Артаньян'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Поддерживается и &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;NULL&lt;/span&gt; — &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;Атос&amp;quot;&lt;/span&gt;, &lt;span class=&quot;kw2&quot;&gt;NULL&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;&amp;quot;Д'Артаньян&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; превратится в условие:
&lt;/p&gt;
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;p.id &lt;span class=&quot;kw1&quot;&gt;IS&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;NULL&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;OR&lt;/span&gt; p.id &lt;span class=&quot;kw1&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'Атос'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'Д&lt;span class=&quot;es0&quot;&gt;\'&lt;/span&gt;Артаньян'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;h4&gt;Сопоставление типа LIKE&lt;/h4&gt;
&lt;p&gt;
Другой вариант сопоставления параметра содержит конфигурация поля title:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'type'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'LIKE%'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Такая конфигурация даст условие вида
&lt;/p&gt;
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;title &lt;span class=&quot;kw1&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'параметр%'&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
где &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'параметр'&lt;/span&gt;&lt;/span&gt; — это экранированный &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/span&gt;&lt;sup&gt;&lt;a name=&quot;ftnref-4&quot; href=&quot;#ftn-4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;
&lt;p&gt;
Если &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/span&gt; является массивом, условие будет составлено для каждого из его элементов, и затем все они объединены через OR (получится как бы IN для LIKE):
&lt;/p&gt;
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;title &lt;span class=&quot;kw1&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'параметр[0]%'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;OR&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;title &lt;span class=&quot;kw1&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'параметр[1]%'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;OR&lt;/span&gt; ...&lt;/div&gt;
&lt;p&gt;
Аналогичным образом можно использовать &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'%LIKE'&lt;/span&gt;&lt;/span&gt; и &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'%LIKE%'&lt;/span&gt;&lt;/span&gt;.
&lt;/p&gt;
&lt;h4&gt;Интервальное сопоставление&lt;/h4&gt;
&lt;p&gt;
Конфигурация поля price_final является примером интервального сопоставления:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'price_final'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'sql'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;price * (100 - discount) / 100&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'type'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'[min,max]'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Указанные ключи параметра ограничивают выборку: первый — снизу, второй — сверху. Условие в данном случае примет вид:&lt;/p&gt;
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;price * &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;100&lt;/span&gt; - discount&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; / &lt;span class=&quot;nu0&quot;&gt;100&lt;/span&gt; &amp;gt;= $_GET&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;price_final&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;AND&lt;/span&gt;&lt;br /&gt;
price * &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;100&lt;/span&gt; - discount&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; / &lt;span class=&quot;nu0&quot;&gt;100&lt;/span&gt; &amp;lt;= $_GET&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;price_final&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Вместо min и max можно указывать любые другие имена ключей, нужно лишь следить за тем, чтобы они совпадали с именами полей формы.
&lt;/p&gt;
&lt;p&gt;
Можно указать только один ключ (например, &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'[min,]'&lt;/span&gt;&lt;/span&gt;), в этом случае будет возможность ограничить выборку только с одной стороны.
&lt;/p&gt;
&lt;p&gt;
Если квадратные скобки заменить на круглые — &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'(min,max)'&lt;/span&gt;&lt;/span&gt; — нестрогое неравенство заменится на строгое (так же, как обозначают интервалы в математике). При этом они не обязательно должны быть одинаковыми: с одной стороны неравенство может быть строгим, а с другой — нет.
&lt;/p&gt;
&lt;h4&gt;Сопоставление типа &amp;laquo;включено/выключено&amp;raquo;&lt;/h4&gt;
&lt;p&gt;
Для такого сопоставления SQL-выражение просто вставляется в запрос в неизменном виде, но лишь если соответствующий параметр присутствует в запросе и отличен от FALSE.
&lt;/p&gt;
&lt;p&gt;
Для поля has_discount с конфигурацией
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'has_discount'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'sql'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;discount &amp;gt; 0&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'type'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'on-off'&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
в запрос попадет условие &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;discount &amp;gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
Это сопоставление лучше всего подходит для полей формы типа checkbox.
&lt;/p&gt;
&lt;h4&gt;&lt;a name=&quot;explicit-where&quot;&gt;&lt;/a&gt;Произвольные условия&lt;/h4&gt;
&lt;p&gt;
Ограничения списка могут не только формироваться на основании параметров поиска, но и быть прямо указаны вручную.
&lt;/p&gt;
&lt;p&gt;
В рассматриваемом примере страница каталога относится к какому-то конкретному производителю. В этом случае условие на manufacturer_id должно выполняться всегда — независимо от содержимого $_GET:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;manufacturer_id = 2&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'where'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Таких произвольных условий может быть сколько угодно. Все они войдут запрос непосредственно в том виде, в котором указаны, без изменений.
&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;limit&quot;&gt;&lt;/a&gt;Разбивка на страницы, LIMIT, получение общего количества строк&lt;/h3&gt;
&lt;p&gt;
Для разбивки на страницы в условия для построения списка нужно включать элемент &lt;i&gt;limit&lt;/i&gt;. В случае, если номер страницы передается в GET-параметре &lt;i&gt;p&lt;/i&gt;, а количество записей на странице может содержаться в параметре &lt;i&gt;N&lt;/i&gt;, код может выглядеть следующим образом:&lt;sup&gt;&lt;a name=&quot;ftnref-5&quot; href=&quot;#ftn-5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'limit'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'page'&lt;/span&gt; &amp;nbsp; &amp;nbsp; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ? &lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; : &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'per_page'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'N'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; ? &lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'N'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; : &lt;span class=&quot;nu0&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
То же самое можно записать в сокращенной форме (как это и сделано в примере):
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'limit'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;, &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'N'&lt;/span&gt;,&lt;span class=&quot;nu0&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// [...] - короткий вариант объявления массивов&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'where'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;, &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// в PHP с версии 5.4&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
При такой форме записи имена ключей в &lt;i&gt;limit&lt;/i&gt; относятся к массиву с параметрами поиска (&lt;i&gt;where&lt;/i&gt;).
&lt;/p&gt;
&lt;p&gt;
Запись вида &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;, &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'N'&lt;/span&gt;,&lt;span class=&quot;nu0&quot;&gt;20&lt;/span&gt;,&lt;span class=&quot;nu0&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/span&gt; устанавливает для количества записей ограничение сверху.
&lt;/p&gt;
&lt;p&gt;
Можно указывать числовые значения явно: &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'limit'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'0, 20'&lt;/span&gt;&lt;/span&gt; или &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'limit'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;100&lt;/span&gt;&lt;/span&gt;. Такая запись
перейдет в LIMIT запроса в неизменном виде.
&lt;/p&gt;
&lt;p&gt;
Общее количество строк без учета LIMIT можно получить, передав методу find() необязательный второй аргумент — переменную, в которую это количество будет записано:&lt;sup&gt;&lt;a name=&quot;ftnref-6&quot; href=&quot;#ftn-6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// $count необязательно должна быть установлена ранее&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$products&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$count&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;h3&gt;&lt;a name=&quot;orderby&quot;&gt;&lt;/a&gt;Сортировка&lt;/h3&gt;
&lt;p&gt;
Указывать сортировку в условиях запроса следует в ключе &lt;i&gt;orderby&lt;/i&gt;. При этом можно ссылаться на элементы массива $columns. Например:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'orderby'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;{*price_final DESC*}, id DESC&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'where'&lt;/span&gt; =&amp;gt; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Фрагмент &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;{*price_final DESC*}&lt;/span&gt; заменится на соответствующее SQL-выражение из массива $columns.
&lt;/p&gt;
&lt;p&gt;
Чтобы дать возможность управлять сортировкой через параметры GET-запроса страницы, в ключ &lt;i&gt;orderby&lt;/i&gt; нужно поместить специальную метку:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'orderby'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'&amp;amp;ord'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'where'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Здесь &lt;i&gt;ord&lt;/i&gt; — ключ массива $_GET, содержащий текущие параметры сортировки.
&lt;/p&gt;
&lt;p&gt;
Соответственно, адрес страницы должен иметь вид
&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;...&amp;amp;ord=(имя поля из конфигурации) (направление)&lt;/span&gt;.
Например, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;...&amp;amp;ord=price_final DESC&lt;/span&gt;.
Метка в &lt;i&gt;orderby&lt;/i&gt; заменится SQL-выражением для выбранного поля&lt;sup&gt;&lt;a name=&quot;ftnref-7&quot; href=&quot;#ftn-7&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;, в результате запрос примет вид:
&lt;/p&gt;
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; price * &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;100&lt;/span&gt; - discount&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; / &lt;span class=&quot;nu0&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;DESC&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Можно комбинировать метку и постоянные части:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'orderby'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;&amp;amp;ord, discount &amp;gt; 0 DESC, ...&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
А также задавать сортировку по умолчанию для случая, если она не указана через GET-параметр:
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'orderby'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;&amp;amp;ord || discount &amp;gt; 0, id DESC&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;h2&gt;Получение и обработка данных&lt;/h2&gt;
&lt;h3&gt;Набор полей списка&lt;/h3&gt;
&lt;p&gt;
Каждому параметру поиска соответствует одноименное поле в результирующем массиве данных. Взглянем еще раз на конфигурацию&lt;sup&gt;&lt;a name=&quot;ftnref-8&quot; href=&quot;#ftn-8&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;:
&lt;/p&gt;
&lt;!--
--&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'id'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'sql'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;p.id&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'price_final'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'sql'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;price * (100 - discount) / 100&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'has_discount'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'sql'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;discount &amp;gt; 0&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Вот как примерно выглядит результат работы метода find():
&lt;/p&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [5] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [id] =&amp;gt; 5&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [price_final] =&amp;gt; 35000&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [title] =&amp;gt; Телевизор&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [has_discount] =&amp;gt; 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [4] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [id] =&amp;gt; 4&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [price_final] =&amp;gt; 1500&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [title] =&amp;gt; Совок&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [has_discount] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;/div&gt;
&lt;p&gt;
Если поле нужно в качестве параметра поиска, но среди конечных данных не требуется, его можно исключить из результирующего массива, поместив в начало ключа специальную последовательность &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;@@:&lt;/span&gt;
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'id'&lt;/span&gt; =&amp;gt; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'@@: has_discount'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'sql'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;discount &amp;gt; 0&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
При такой конфигурации элемент &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;has_discount&lt;/span&gt; среди полученных данных будет отсутствовать.
&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;getSingle&quot;&gt;&lt;/a&gt;Получение данных одиночной сущности&lt;/h3&gt;
&lt;p&gt;
Для получения данных одиночной сущности по её идентификатору служит метод getSingle():
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt; = &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; Products;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$product&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;getSingle&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$product_id&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Поля, которые для списка не требутся и нужны только для случая одиночной сущности, можно выделить явным образом. Их объявление должно начинаться с последовательности &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;@:&lt;/span&gt;:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;@: p.text&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Поле &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;p.text&lt;/span&gt; при поиске и работе со списками запрашиваться из БД не будет, что даёт определенный выигрыш в быстродействии.
&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;processData()&quot;&gt;&lt;/a&gt;Пост-обработка данных&lt;/h3&gt;
&lt;p&gt;
К каждой строке, полученной из БД, могут быть применены дополнительные преобразования. Для этого нужно определить метод &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;processData&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;. Например:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;class&lt;/span&gt; Products &lt;span class=&quot;kw2&quot;&gt;extends&lt;/span&gt; _List &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;...&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; processData&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;re0&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'url'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span class=&quot;st0&quot;&gt;&amp;quot;/products/$row[id].html&amp;quot;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$row&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Каждой записи результирующих данных добавится ключ &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;url&lt;/span&gt;
&lt;/p&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [5] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [id] =&amp;gt; 5&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [price_final] =&amp;gt; 35000&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [title] =&amp;gt; Телевизор&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [has_discount] =&amp;gt; 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /products/5.html&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [4] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [id] =&amp;gt; 4&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [price_final] =&amp;gt; 1500&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [title] =&amp;gt; Совок&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [has_discount] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /products/4.html&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;/div&gt;
&lt;p&gt;
Пост-обработка выполняется после &lt;a href=&quot;#value_type&quot;&gt;приведения типов&lt;/a&gt;.
&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;getSpecialData&quot;&gt;&lt;/a&gt;Получение специальных данных&lt;/h3&gt;
&lt;p&gt;
Периодически бывает нужно получить не просто список сущностей со всеми полями, а какой-то специальный набор их данных.
Для этого служит метод &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;getSpecialData&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;.
&lt;p&gt;
На вход метод принимает набор SQL-выражений для будущих колонок результата, а также массив с условиями поиска (аналогичный тому, что используется для методов &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;find&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; и &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;findIds&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;).
&lt;/p&gt;
&lt;p&gt;
Например, для заданных условий поиска получить ценовой диапазон и количество товаров со скидкой от 50% можно с помощью следующего кода:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;-&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;manufacturer_id = 2&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'where'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$special_data&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;getSpecialData&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;SUM(discount &amp;gt;= 50) AS sale_count&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;MIN({*price_final*}) AS price_min&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;MAX({*price_final*}) AS price_max&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Здесь &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;{*price_final*}&lt;/span&gt; — ссылка на SQL-выражение в массиве &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;$columns&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
Содержимое $special_data будет примерно следующим:&lt;/p&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Array&lt;br /&gt;
(&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [0] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [sale_count] =&amp;gt; 35&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [price_min] =&amp;gt; 1000&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [price_max] =&amp;gt; 12500&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
)&lt;/div&gt;
&lt;p&gt;Получить текст SQL-запроса вместо результата можно с помощью метода &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;getSpecialDataSQL&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;, принимающего те же аргументы, что и &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;getSpecialData&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;
Если результат заведомо состоит из одной строки, удобно использовать метод &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;getSpecialDataRow&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;, он вернёт массив меньшего уровня вложенности.
&lt;/p&gt;
&lt;p&gt;
Другой пример — получение всех производителей (точнее, их идентификаторов), товары которых удовлетворяют определенным условиям:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = ...;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$special_data&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;getSpecialData&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;DISTINCT p.manufacturer_id&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Здесь методу передается одна колонка вместо массива, что является инструкцей вернуть вместо табличного результата колоночный:
&lt;/p&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Array&lt;br /&gt;
(&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [0] =&amp;gt; 2&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [1] =&amp;gt; 5&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [2] =&amp;gt; 10&lt;br /&gt;
)&lt;/div&gt;
&lt;p&gt;Для получения результата, который состоит из одной &lt;i&gt;ячейки&lt;/i&gt;, предназначен метод &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;getSpecialDataCell&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;. Первый аргумент для него - строка с SQL-выражением, а не массив таких строк:&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = ...;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$special_data&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;getSpecialDataCell&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;COUNT(*)&amp;quot;&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;h2&gt;
	&lt;a name=&quot;DDL&quot;&gt;&lt;/a&gt;
	DDL: изменение структуры данных таблицы
&lt;/h2&gt;
&lt;p&gt;
ORM снабжен средствами генерации запросов, изменяющих структуру хранения данных (&lt;i&gt;DDL —
&lt;b&gt;d&lt;/b&gt;ata &lt;b&gt;d&lt;/b&gt;efinition &lt;b&gt;l&lt;/b&gt;anguage&lt;/i&gt;).
&lt;/p&gt;
&lt;h3&gt;
    &lt;a name=&quot;generateMainTableSQL&quot;&gt;&lt;/a&gt;
     &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CREATE TABLE&lt;/span&gt;&lt;/span&gt; для главной таблицы
&lt;/h3&gt;
&lt;p&gt;ORM позволяет выполнить SQL-запрос на создание главной таблицы или получить его содержимое.&lt;/p&gt;
&lt;p&gt;Для этого в конфигурации соответствующих полей нужно указать ключ
    &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;column_definition&lt;/span&gt;, а также создать специальное свойство класса под
    названием &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;$mainTableConfig&lt;/span&gt;:&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;kw2&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$mainTableConfig&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'name'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'products'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'alias'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'keys'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// определения ключей списком&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'KEY (price)'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'KEY (discount)'&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'properties'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'ENGINE'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'MyISAM'&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// можно в виде пар ключ=значение&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'AUTO_INCREMENT = 7'&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// а можно просто строкой&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'id'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'sql'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;p.id&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'column_definition'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'column_definition'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'VARCHAR(255) NOT NULL'&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;Создать таблицу можно так:&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;createMainTable&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;Вызвав вместо этого метод &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;generateMainTableSQL&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;, получим текст
запроса:&lt;/p&gt;
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CREATE TABLE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;EXISTS&lt;/span&gt; products &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; id &lt;span class=&quot;kw2&quot;&gt;INT&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;UNSIGNED&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;NOT NULL&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;AUTO_INCREMENT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;PRIMARY KEY&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; title &lt;span class=&quot;kw2&quot;&gt;VARCHAR&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;NOT NULL&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;price&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;discount&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;ENGINE&lt;/span&gt; = &lt;span class=&quot;kw1&quot;&gt;MyISAM&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;AUTO_INCREMENT&lt;/span&gt; = &lt;span class=&quot;nu0&quot;&gt;7&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Запрос без &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;EXISTS&lt;/span&gt;&lt;/span&gt; в обоих методах можно получить, передав
 &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;false&lt;/span&gt;&lt;/span&gt; в качестве аргумента.&lt;/p&gt;
&lt;h3&gt;
	&lt;a name=&quot;changeOrModifycolumn&quot;&gt;&lt;/a&gt;
	Модификация колонок таблицы
&lt;/h3&gt;
&lt;p&gt;
	Методы &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;changeOrModifycolumn&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; и
	&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;changeOrModifycolumnsQL&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; служат для исполнения запросов
	&lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CHANGE&lt;/span&gt;/&lt;span class=&quot;kw1&quot;&gt;MODIFY&lt;/span&gt;/&lt;span class=&quot;kw1&quot;&gt;RENAME&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;column&lt;/span&gt;&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
	Рассмотрим пример: нам требуется поменять тип колонки &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;title&lt;/span&gt; на
	&lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;TEXT&lt;/span&gt;&lt;/span&gt;. Для этого нужно:
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Изменить её &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;column_definition&lt;/span&gt; в
	&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;
		Выполнить код: &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;changeOrModifycolumn&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;
		(Аргументом здесь является ключ в &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt;&lt;/span&gt;.)
	&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Другой пример — нужно не только поменять тип колонки, но и переименовать её в
	&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;name&lt;/span&gt;. В этом случае последовательность действий такая:
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Изменить &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;column_definition&lt;/span&gt; в
	&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;Выполнить код: &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;changeOrModifycolumn&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'name'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;Изменить ключ в &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt;&lt;/span&gt; с &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;title&lt;/span&gt; на &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;name&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Если требуется только переименовать колонку:
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;
		Выполнить код: &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;changeOrModifycolumn&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'title'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'name'&lt;/span&gt;, &lt;span class=&quot;kw2&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/span&gt;
		&lt;br&gt;
		Третий аргумент включает работу в режиме &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;RENAME&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;column&lt;/span&gt;&lt;/span&gt;.
	&lt;/li&gt;
	&lt;li&gt;Изменить ключ в &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt;&lt;/span&gt; с &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;title&lt;/span&gt; на &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;name&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
	Вызвав &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;changeOrModifycolumnsQL&lt;/span&gt; с теми же аргументами, можно получить
	текст запроса без выполнения.
&lt;/p&gt;
&lt;h2&gt;
	&lt;a name=&quot;value_type&quot;&gt;&lt;/a&gt;
	Приведение к типу при получении данных
&lt;/h2&gt;
&lt;p&gt;
PHP при получении данных из MySQL, преобразует все значения, кроме
&lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;NULL&lt;/span&gt;&lt;/span&gt;, в строки.
&lt;/p&gt;
&lt;p&gt;
Можно настроить поля в &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt;&lt;/span&gt; так, чтобы данные преобразовывались в
значения нужного типа.
&lt;/p&gt;
&lt;p&gt;
Это делается либо в явном виде с помощью ключа &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;value_type&lt;/span&gt;, либо
автоматически на основании &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;column_definition&lt;/span&gt; (см. ниже).
&lt;/p&gt;
&lt;p&gt;
&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;value_type&lt;/span&gt; может принимать следующие значения:
&lt;/p&gt;
&lt;h4&gt;&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'int'&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;
Величина будет преобразована в целое число (&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;intval&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;).
&lt;/p&gt;
&lt;p&gt;
Такой &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;value_type&lt;/span&gt; автоматически устанавливается полям, которые согласно
&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;column_definition&lt;/span&gt; имеют тип из семейства &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;INTEGER&lt;/span&gt;&lt;/span&gt;
 или &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;DECIMAL&lt;/span&gt;&lt;/span&gt; без дробной части.
&lt;/p&gt;
&lt;h4&gt;&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'float'&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;
Величина будет преобразована в число с плавающей точкой (&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;floatval&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;).
&lt;/p&gt;
&lt;p&gt;
Автоматически устанавливается полям, которые в &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;column_definition&lt;/span&gt;
имеют тип &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;FLOAT&lt;/span&gt;&lt;/span&gt;,
 &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;DOUBLE&lt;/span&gt;&lt;/span&gt; или &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;DECIMAL&lt;/span&gt;&lt;/span&gt; с дробной частью.
&lt;/p&gt;
&lt;h4&gt;&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'json'&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;
Этот тип автоматически устанавливается колонкам, имеющий одноименный тип в
&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;column_definition&lt;/span&gt; и приводит к преобразованию JSON-строки в
массив или скалярную величину.
&lt;/p&gt;
&lt;h4&gt;&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'bool'&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;
Величина будет преобразована в логическое значение — &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;true&lt;/span&gt;&lt;/span&gt; или
&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;false&lt;/span&gt;&lt;/span&gt;. &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;NULL&lt;/span&gt;&lt;/span&gt;, как и во всех других случаях, будет
оставлен без изменений.
&lt;/p&gt;
&lt;p&gt;
Этот тип преобразования устанавливается &lt;i&gt;только вручную в явном виде&lt;/i&gt;.
&lt;/p&gt;
&lt;h4&gt;&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'datetime'&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;
Такое преобразование можно использовать для значений даты/времени. Из обычных строк они
превратятся в экземпляры специального класса, производного от &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;DateTime&lt;/span&gt;,
который снабжен методом &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;__toString&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;, благодаря чему, при надобности
(например, при выводе через &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;echo&lt;/span&gt;&lt;/span&gt; или склейке с другими строками),
преобразуются в стандартную строку даты. При этом с ними можно работать как с обычными
объектами &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;DateTime&lt;/span&gt; — смещать по временным интервалам, выводить в
указанном формате и т.п.:
&lt;/p&gt;
&lt;p&gt;
Этот тип преобразования, как и &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'bool'&lt;/span&gt;&lt;/span&gt;, устанавливается &lt;i&gt;только
вручную&lt;/i&gt;.
&lt;/p&gt;
&lt;h4&gt;Отмена преобразования&lt;/h4&gt;
&lt;p&gt;
Если в конфигурации явно указать &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;value_type&lt;/span&gt; равным
&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;false&lt;/span&gt;&lt;/span&gt;, преобразование типа выполняться не будет независимо от
&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;column_definition&lt;/span&gt;.
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;grouping-join&quot;&gt;&lt;/a&gt;JOIN подчиненных таблиц с группировкой&lt;/h2&gt;
&lt;p&gt;В случае связи с другой таблицей типа «один ко многим» можно настроить получение из неё
    данных с использованием различных агрегирующих функций.&lt;/p&gt;
&lt;p&gt;Рассмотрим пример: для каждого товара нужно узнать сумму продаж.&lt;/p&gt;
&lt;p&gt;Предположим, продажи хранятся в таблице &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;order_items&lt;/span&gt; с колонками:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;product_id&lt;/span&gt; — id товара&lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;price&lt;/span&gt; — цена продажи&lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;quantity&lt;/span&gt; — количество единиц&lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;sold&lt;/span&gt; — был ли товар фактически продан&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Конфигурацию класса нужно дополнить:&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$tables&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;GROUPING LEFT JOIN order_items AS i ON i.product_id = p.id AND i.sold = 1&amp;quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// Нужен именно LEFT JOIN, т.к. продаж товара может не быть&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw2&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;total_sales_cost&amp;quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;type&amp;quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;[min,max]&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;sql&amp;quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;SUM(i.price * i.quantity)&amp;quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Ключевое слово &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;GROUPING&lt;/span&gt; указывает на необходимость группировки
    результата по уникальному идентификатору главной таблицы, которая будет включена
    в запрос механизмом ORM
    автоматически. (Оно не является синтаксической конструкцией MySQL и будет исключено из
    итогового текста запроса.)
&lt;/p&gt;
&lt;p&gt;
    С &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;total_sales_cost&lt;/span&gt; можно обращаться как с обычным параметром,
    используя его при фильтрации и группировке:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// Товары, которых продано на миллион или более:&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'where'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'total_sales_cost'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'min'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;1000000&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// 10 самых продаваемых товаров&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'orderby'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'{*total_sales_cost*} DESC'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'limit'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;Рассмотрим другой, немного более сложный случай: получение суммы покупок клиентов.&lt;/p&gt;
&lt;p&gt;В этом случае связь главной таблицы — таблицы клиентов — с таблицей продаж не прямая, а
    через промежуточную таблицу заказов:&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$tables&lt;/span&gt; = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;FROM clients AS c&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;GROUPING LEFT JOIN orders AS o ON o.client_id = o.id&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;LEFT JOIN order_items AS i ON i.product_id = p.id AND i.sold = 1&amp;quot;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
    Здесь &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;GROUPING&lt;/span&gt; указывается для таблицы
    &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;orders&lt;/span&gt;, т.к. связь «один ко многим» начинается именно с неё.
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;related&quot;&gt;&lt;/a&gt;Связанные сущности&lt;/h2&gt;
&lt;p&gt;
Под связанной понимается сущность другого рода, на которую через уникальный идентификатор ссылается некоторое поле данной сущности.
&lt;/p&gt;
&lt;p&gt;
Например, у каждого товара есть производитель, id которого хранится в поле &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;manufacturer_id&lt;/span&gt;. Производителям соответствует свой собственный класс &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;Manufacturers&lt;/span&gt;, также унаследованный от &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;_List&lt;/span&gt;, где описывается вся логика работы с ними: набор полей, параметры поиска, пост-обработка данных и т.д.
&lt;/p&gt;
&lt;p&gt;
Чтобы этой логикой пользоваться в классе товаров, нужно установить его связь с классом производителей. Это делается через соответствующее поле (в данном случае — &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;manufacturer_id&lt;/span&gt;), которому в конфигурации устанавливается свойство &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;related&lt;/span&gt;:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;class&lt;/span&gt; Products &lt;span class=&quot;kw2&quot;&gt;extends&lt;/span&gt; _List &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'manufacturer_id'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'related'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'manufacturer'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Manufacturers'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// 'имя ключа' =&amp;gt; 'класс' (объяснение см. далее по тексту)&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;kw2&quot;&gt;class&lt;/span&gt; Manufacturers &lt;span class=&quot;kw2&quot;&gt;extends&lt;/span&gt; _List &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$tables&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;FROM manufacturers m&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;&amp;quot;country_id&amp;quot;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; processData&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;re0&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'url'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span class=&quot;st0&quot;&gt;&amp;quot;/manufacturers/$row[id].html&amp;quot;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$row&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Установление такой связи даёт две важных возможности.
&lt;/p&gt;
&lt;h3&gt;Поиск по свойствам связанных сущностей&lt;/h3&gt;
&lt;p&gt;
Среди параметров поиска могут быть относящиеся именно к производителям, а не только к самим товарам.
&lt;/p&gt;
&lt;p&gt;
При передаче методу &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;find&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; в составе &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'where'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/span&gt; они должны быть сгруппированы в подмассив &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;manufacturer&lt;/span&gt; (имя подмассива указывается в конфигурации в качестве ключа в &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;related&lt;/span&gt; — см. выше).
&lt;/p&gt;
&lt;p&gt;
Например, включать в форму поиска поле для указания страны производителя нужно с атрибутом &lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;name=&amp;quot;manufacturer[country_id]&amp;quot;&lt;/span&gt;:
&lt;/p&gt;
&lt;form class=&quot;example&quot;&gt;
	Цена от &lt;input name=&quot;price_final[min]&quot;&gt;
	     до &lt;input name=&quot;price_final[max]&quot;&gt;
	&lt;input name=&quot;has_discount&quot; type=&quot;checkbox&quot;&gt; скидка
	&lt;br&gt;
	Название (начинается с) &lt;input name=&quot;title&quot;&gt;
	&lt;br&gt;
	Страна-производитель:
	&lt;select name=&quot;manufacturer[country_id]&quot;&gt;
		&lt;option value=&quot;1&quot;&gt;Россия&lt;/option&gt;
		&lt;option value=&quot;2&quot;&gt;США&lt;/option&gt;
		&lt;option value=&quot;3&quot;&gt;Германия&lt;/option&gt;
	&lt;/select&gt;
	&lt;button&gt;OK&lt;/button&gt;
&lt;/form&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;form&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Цена от &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;price_final[min]&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;до &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;price_final[max]&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;has_discount&amp;quot;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; скидка&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;br&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Название (начинается с) &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;br&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Страна производства:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;select&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;manufacturer[country_id]&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;option&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;value&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Россия&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;option&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;value&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;США&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;option&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;value&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;3&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Германия&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;button&amp;gt;&lt;/span&gt;&lt;/span&gt;OK&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
При этом сам вызов &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;find&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; не меняется никак:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'where'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'orderby'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'[ord]'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'limit'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'p'&lt;/span&gt;, &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'N'&lt;/span&gt;,&lt;span class=&quot;nu0&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt; = &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; Products;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$products&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Единственное, что требуется — составить форму так, чтобы параметры поиска, относящиеся к производителю, приходили в подмассиве &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'manufacturer'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/span&gt;.
&lt;/p&gt;
&lt;h3&gt;Получение данных связанных сущностей&lt;/h3&gt;
&lt;p&gt;
У каждой записи из &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;$products&lt;/span&gt; автоматически появится подмассив &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;manufacturer&lt;/span&gt;:
&lt;/p&gt;
&lt;div class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt; &amp;nbsp; &amp;nbsp;...&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [5] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [id] =&amp;gt; 5&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [price_final] =&amp;gt; 35000&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [title] =&amp;gt; Телевизор&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [has_discount] =&amp;gt; 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /products/5.html&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [manufacturer] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [id] =&amp;gt; 3&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [title] =&amp;gt; SONY&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [country_id] =&amp;gt; 7&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /manufacturers/3.html&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; [4] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [id] =&amp;gt; 4&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [price_final] =&amp;gt; 1500&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [title] =&amp;gt; Совок&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [has_discount] =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /products/4.html&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [manufacturer] =&amp;gt; Array&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [id] =&amp;gt; 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [title] =&amp;gt; Полимербытхимпром&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [country_id] =&amp;gt; 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [url] =&amp;gt; /manufacturers/1.html&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;/div&gt;
&lt;h2&gt;Добавление, изменение и удаление записей&lt;/h2&gt;
&lt;h3&gt;&lt;a name=&quot;write&quot;&gt;&lt;/a&gt;write()&lt;/h3&gt;
&lt;p&gt;
Для добавления записей и изменения их данных служит метод write(). В качестве аргументов он принимает массив полей записи и её идентификатор:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt; = &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; Products;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$_POST&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'id'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;co1&quot;&gt;// данные пришли из формы со страницы вида ?id=...&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Если идентификатор не указывать, будет добавлена новая запись, а в ответ возращен ее идентификатор:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt; = &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; Products;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$new_id&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
При записи данные экранируются (используется &lt;a href=&quot;http://webew.ru/articles/3237.webew#mysql_write_row&quot;&gt;mysql_write_row()&lt;/a&gt;), однако никаких проверок метод в себя не включает. Для этого рекомендуется использовать специальный &lt;a href=&quot;http://webew.ru/articles/5000.webew&quot;&gt;инструмент для проверки правильности заполнения веб-форм&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;write&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; может работать также в режимах
&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;DUPLICATE&lt;/span&gt;, &lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;IGNORE&lt;/span&gt; и
&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;REPLACE&lt;/span&gt;. Использование аналогично
&lt;a href=&quot;https://webew.ru/articles/3237.webew#mysql_write_row&quot;&gt;mysql_write_row()&lt;/a&gt;, за
исключением того, что не требуется передавать имя таблицы.
&lt;/p&gt;
&lt;p&gt;
&lt;a name=&quot;insertOnDuplicateKeyUpdateAndReturnId&quot;&gt;&lt;/a&gt;
Если таблица имеет уникальные ключи помимо первичного, для вставки данных в режиме
&lt;span class=&quot;code text&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;DUPLICATE&lt;/span&gt;
можно использовать метод &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;insertOnDuplicateKeyUpdateAndReturnId&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;,
который позволяет получить значение автоинкрементного поля для затронутой строки, будь то вновь
 вставленная или обновленная существующая:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$product_id&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;insertOnDuplicateKeyUpdateAndReturnId&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$data&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$unique_keys&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;h3&gt;&lt;a name=&quot;delete&quot;&gt;&lt;/a&gt;delete()&lt;/h3&gt;
&lt;p&gt;
Метод delete() в качестве аргумента принимает уникальный идентификатор (автоматически экранируется) и просто удаляет соответствующую запись из таблицы, возвращая TRUE в случае успеха:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$id&lt;/span&gt; = ...;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt; = &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; Products;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;h2&gt;Дополнительные сведения и возможности&lt;/h2&gt;
&lt;p&gt;
В основе данной библиотеки лежит подход к построению списков, сущность которого заключается в следующем: сначала из БД с учетом условий, сортировки и LIMIT извлекаются уникальные идентификаторы строк, после чего для этих строк запрашиваются остальные данные. Обоснованию и разъяснению этого подхода посвящена &lt;a href=&quot;http://webew.ru/articles/4856.webew&quot; title=&quot;Архитектурная концепция программирования при работе со списками в веб-приложениях на основе PHP и MySQL&quot;&gt;отдельная статья&lt;/a&gt;.
&lt;/p&gt;
&lt;div class=&quot;footnote&quot;&gt;
					&lt;p&gt;
						1.
						&lt;a name=&quot;ftn-1&quot; href=&quot;#ftnref-1&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	В классической реализации объектно-реляционного отображения каждой строке базы данных соответствует экземпляр объекта. Предлагаемая реализация не является классической: каждой строке здесь соответствует просто ассоциативный массив данных.
					&lt;/p&gt;
					&lt;p&gt;
						2.
						&lt;a name=&quot;ftn-2&quot; href=&quot;#ftnref-2&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Используется функция &lt;a href=&quot;http://webew.ru/articles/3237.webew#mysql_escape&quot;&gt;mysql_escape()&lt;/a&gt;.
					&lt;/p&gt;
					&lt;p&gt;
						3.
						&lt;a name=&quot;ftn-3&quot; href=&quot;#ftnref-3&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Каждое из условий заключается в круглые скобки, чтобы ограничить действие оператора OR, если таковой встретится в выражении. То же самое касается произвольных условий (см. &lt;a href=&quot;#explicit-where&quot;&gt;соответствующий раздел&lt;/a&gt;).
					&lt;/p&gt;
					&lt;p&gt;
						4.
						&lt;a name=&quot;ftn-4&quot; href=&quot;#ftnref-4&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Следует отметить, что в конфигурации поля title отсутствует ключ &lt;i&gt;sql&lt;/i&gt;. В таких случаях в качестве SQL-выражения используется непосредственно имя параметра.
					&lt;/p&gt;
					&lt;p&gt;
						5.
						&lt;a name=&quot;ftn-5&quot; href=&quot;#ftnref-5&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
						Нумерация страниц начинается с единицы.
					&lt;/p&gt;
					&lt;p&gt;
						6.
						&lt;a name=&quot;ftn-6&quot; href=&quot;#ftnref-6&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Если переменная для записи общего количества строк передана, будет выполнен отдельный запрос вида &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;*&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;. Вопреки распространенной практике, такой вариант обладает более высокой производительностью, чем использование SQL_CALC_FOUND_ROWS. Подробнее см. &lt;a href=&quot;http://sqlinfo.ru/forum/viewtopic.php?pid=38337&quot;&gt;http://sqlinfo.ru/forum/viewtopic.php?pid=38337&lt;/a&gt;
					&lt;/p&gt;
					&lt;p&gt;
						7.
						&lt;a name=&quot;ftn-7&quot; href=&quot;#ftnref-7&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
						Если GET-параметр сортировки не соответствует ни одному из ключей массива $columns, он будет просто проигнорирован.
					&lt;/p&gt;
					&lt;p&gt;
						8.
						&lt;a name=&quot;ftn-8&quot; href=&quot;#ftnref-8&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
Конфигурация в примере имеет полную форму записи. Можно использовать также сокращенные формы:
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$columns&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// все нижеуказанные варианты записи равнозначны&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'column'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// полная запись&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'sql'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'table.column'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'column'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'table.column'&lt;/span&gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'table.column'&lt;/span&gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'column'&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// если среди всех задействованных таблиц нет колонок с одинаковыми именами,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// указывать таблицу в явном виде необязательно&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
					&lt;/p&gt;
					&lt;p&gt;
						9.
						&lt;a name=&quot;ftn-9&quot; href=&quot;#ftnref-9&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
						Метод find(), собственно говоря, состоит из вызова findIds() и getList().
					&lt;/p&gt;
					&lt;p&gt;
						10.
						&lt;a name=&quot;ftn-10&quot; href=&quot;#ftnref-10&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
	Из-за этой возможности важно проверять пользовательские данные в случае, если они передаются методу напрямую. Например, для &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$P&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;getList&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'ids'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; важно убедиться, что в GET-запросе передается именно массив чисел, а не строка, иначе возможна SQL-инъекция.
					&lt;/p&gt;
					&lt;/div&gt;</description>
</item>
<item>
  <title>PHP: инструмент для проверки правильности заполнения веб-форм</title>
  <link>http://webew.ru/articles/5000.webew</link>
  <guid>http://webew.ru/articles/5000.webew</guid>
  <pubDate>Fri, 09 Aug 2013 19:14:10 +0400</pubDate>
  <description>&lt;script&gt; var CONTENTS_LEVEL = 2 &lt;/script&gt;
&lt;p&gt;
Вниманию читателей предлагается простое средство для проверки форм (в том числе файловых полей и изображений в частности), позволяющее свести написание необходимого кода к составлению конфигурационного массива, в котором можно описать даже самые замысловатые варианты, а если имеющейся гибкости не хватит - легко привлечь сторонний функционал.
&lt;/p&gt;
&lt;p&gt;
Средство реализовано в виде функции, которая в качестве аргументов принимает массив с настройками проверок и массивы с данными запросов (обычно $_GET или $_POST), а в результате работы возвращает одномерный массив строк с сообщениями об ошибках. Код функции можно скачать &lt;a name=&quot;download&quot; href=&quot;http://webew.ru/f/ktSdpYjg.php&quot; target=&quot;_blank&quot;&gt;здесь&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Каждый элемент массива с настройками соответствует ключу запроса (читай полю формы), и в нём перечисляются инструкции, по которым следует выполнять проверки.
&lt;/p&gt;
&lt;h2&gt;Базовые проверки&lt;/h2&gt;
&lt;p&gt;
Рассмотрим в качестве примера форму для заполнения полей почтового отправления, куда пользователь обязательно должен ввести наименование получателя, почтовый адрес, индекс и вес посылки, а телефон и адрес электронной почты - по желанию, но при этом последний нужно проверить на правильность.
&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;form&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Получатель* &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;fio&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Адрес* &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;address&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Почтовый индекс* &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;postcode&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; Вес отправления, кг* &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;weight&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Телефон &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;phone&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; E-mail &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;email&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;button&amp;gt;&lt;/span&gt;&lt;/span&gt;Отправить&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Вот как будет выглядеть код для выполнения проверки:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$check_cfg&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'fio'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Укажите получателя отправления.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'address'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Укажите адрес.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'postcode'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Укажите почтовый индекс места назначения.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'/&lt;span class=&quot;es0&quot;&gt;\d&lt;/span&gt;{6}/'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Почтовый индекс должен состоять из шести цифр.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'weight'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Укажите примерный вес отправления.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'&amp;gt;= 0.2'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Минимальный регистрируемый вес отправления — 0.2 кг'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'&amp;lt; 10'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Отправления тяжелее 10 кг не принимаются.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'email'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'/^&lt;span class=&quot;es0&quot;&gt;\w&lt;/span&gt;[&lt;span class=&quot;es0&quot;&gt;\w&lt;/span&gt;.-]*@(&lt;span class=&quot;es0&quot;&gt;\w&lt;/span&gt;+&lt;span class=&quot;es0&quot;&gt;\.&lt;/span&gt;)+&lt;span class=&quot;es0&quot;&gt;\w&lt;/span&gt;{2,6}$/'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Адрес электронной почты введён некорректно.'&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$errors&lt;/span&gt; = check_form_errors&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$check_cfg&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;
Как уже было сказано выше, каждому из полей формы соответствует набор инструкций, последовательно применяемых для выполнения проверок. Разберём каждую из них:
&lt;/p&gt;
&lt;p&gt;
&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'текст'&lt;/span&gt;&lt;/span&gt; - означает &quot;проверить, что поле присутствует в запросе и заполнено (имеет ненулевую длину без учета пробелов по краям), в противном случае использовать &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'текст'&lt;/span&gt;&lt;/span&gt; в качестве сообщения об ошибке&quot;. Для поля поля address эта проверка является единственной, и набор инструкция для него вместо
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'address'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Укажите адрес.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
можно записать в сокращенной форме: &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'address'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Укажите адрес.'&lt;/span&gt;&lt;/span&gt;, как это сделано для поля fio.
&lt;/p&gt;
&lt;p&gt;
Инструкция вида &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'/.../'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'текст'&lt;/span&gt;&lt;/span&gt; (ключ начинается и заканчивается слэшом) приводит к проверке поля регулярным выражением, содержащимся в ключе, в случае несовпадения с которым &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'текст'&lt;/span&gt;&lt;/span&gt; будет использован в качестве сообщения об ошибке. В регулярном выражении можно использовать модификаторы, поместив их после закрывающего слэша.
&lt;/p&gt;
&lt;p&gt;
Инструкции, где в ключе сначала идёт знак какого-либо неравенства, обрабатываются буквально так: &amp;laquo;применить неравенство точно в указанном виде, подставив слева значение поля; если неравенство неверно — использовать текст в качестве сообщения об ошибке&amp;raquo;&lt;sup&gt;&lt;a name=&quot;ftnref-1&quot; href=&quot;#ftn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;
&lt;p&gt;
Окружающие пробелы удаляются из содержимого полей&lt;sup&gt;&lt;a name=&quot;ftnref-2&quot; href=&quot;#ftn-2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; до начала выполнения проверок, так что учитывать их возможное присутствие при составлении инструкций не нужно.
&lt;/p&gt;
&lt;p&gt;
Важно отметить, что все инструкции, кроме &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt;&lt;/span&gt;, выполняются только когда поле заполнено&lt;sup&gt;&lt;a name=&quot;ftnref-3&quot; href=&quot;#ftn-3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;. Поэтому, если отправить вышеуказанную форму, не заполнив ни одно поле, то, например, для почтового индекса и для веса сработают только первые из сообщений об ошибке, а для email ошибок вообще не будет.
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;functions&quot;&gt;&lt;/a&gt;Проверки с помощью сторонних функций&lt;/h2&gt;
&lt;p&gt;
Проверки можно проводить и с помощью функций. Такие проверки могут быть двух типов.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;#functions-1&quot;&gt;Первый тип&lt;/a&gt; реализуется на основе функций, возвращаещих в результате работы логическую величину (TRUE или FALSE). В случае FALSE считается, что проверка не пройдена, и задействуется сообщение об ошибке.
&lt;/p&gt;
&lt;p&gt;
При проверках &lt;a href=&quot;#functions-2&quot;&gt;второго типа&lt;/a&gt; предполагается, что функция в результате работы вернёт свой собственный массив с сообщениями об ошибках, который и будет дописан к уже составленному при выполнении предыдущих проверок.
&lt;/p&gt;
&lt;p&gt;
Рассмотрим оба этих типа на примерах.
&lt;/p&gt;
&lt;p&gt;
&lt;a name=&quot;functions-1&quot;&gt;&lt;/a&gt;
Предположим, решено проверять также номер телефона, но использовать для этого одно регулярное выражение неудобно, и лучше написать для проверки специальную функцию — скажем, validate_phone() — которая в качестве аргумента принимает номер телефона, а в ответ возвращает, правильный телефон или нет. Вот как будут выглядеть инструкции для поля phone в таком случае:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'phone'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'validate_phone()'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Номер телефона указан некорректно. Проверьте правильность написания.'&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
При такой форме записи функции в качестве единственного аргумента передаётся значение соответствующего поля.
&lt;/p&gt;
&lt;p&gt;
Функции можно передать и дополнительные аргументы. В таком случае запись инструкции немного усложнится:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'phone'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'validate_phone()'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'text'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Номер телефона указан некорректно. Проверьте правильность написания.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'args'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'{*value*}'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'495'&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$some_var&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Вообще говоря, полная запись любой инструкции включает в себя элемент &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'text'&lt;/span&gt;&lt;/span&gt;. Например, проверка на заполнение поля fio в развернутом виде выглядит так:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'fio'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'text'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Укажите получателя отправления.'&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Если инструкция записана в таком, развернутом, виде, и элемент &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'text'&lt;/span&gt;&lt;/span&gt; в ней отсутствует, проверка не приводит к регстрации ошибки ни в каком случае, независимо от своего результата. (Это свойство важно для некоторых случаев, речь о которых пойдет далее).
&lt;/p&gt;
&lt;p&gt;
{*value*} — специальная метка, вместо которой будет подставлено значение поля. Её можно использовать и в текстах ошибок (это касается любых проверок, не только на основе функций). К примеру:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'email'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'/^&lt;span class=&quot;es0&quot;&gt;\w&lt;/span&gt;[&lt;span class=&quot;es0&quot;&gt;\w&lt;/span&gt;.-]*@(&lt;span class=&quot;es0&quot;&gt;\w&lt;/span&gt;+&lt;span class=&quot;es0&quot;&gt;\.&lt;/span&gt;)+&lt;span class=&quot;es0&quot;&gt;\w&lt;/span&gt;{2,6}$/'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Введённый адрес e-mail — {*value*} — некорректен.'&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
&lt;a name=&quot;functions-2&quot;&gt;&lt;/a&gt;
Инструкции, включающие &lt;a href=&quot;#functions&quot;&gt;второй тип&lt;/a&gt; проверок, сходны по виду и отличаются лишь наличием знака &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'+'&lt;/span&gt;&lt;/span&gt; перед именем функции.
&lt;/p&gt;
&lt;p&gt;
Допустим, для проверки строки адреса стали использовать функцию find_address_errors(), которая в данной ей адресной строке ищет разнообразные ошибки и возвращает их в виде строки или списка (массива строк). Инструкции для поля address в этом случае станут выглядеть так:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'address'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Укажите адрес.'&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// Эта проверка остается без изменений&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'+find_address_errors()'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;span class=&quot;co1&quot;&gt;// тексты ошибок находятся в коде функции&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Дополнительные аргументы, при необходимости, следует передавать так же, как и для &lt;a href=&quot;functions-1&quot;&gt;первого типа инструкций&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a name=&quot;functions-2a&quot;&gt;&lt;/a&gt;Альтернативный вариант провести проверку второго типа — определить функцию прямо тут же:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'address'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Укажите адрес.'&lt;/span&gt;, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$field_name&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// Этой функции передается весь массив с данными запроса ($_GET или $_POST)&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// а также название поля, для которого идет проверка.&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$value&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$field_name&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;; &lt;span class=&quot;co1&quot;&gt;// Так можно получить значение поля&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// В случае обнаружения ошибок нужно вернуть их тексты&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// в виде строки или массива строк&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Нужно еще раз сказать, что проверки с помощью функций, как и любые другие, проводятся только в том случае, если поле заполнено.
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;nested&quot;&gt;&lt;/a&gt;Вложенные проверки&lt;/h2&gt;
&lt;p&gt;
Бывают случаи, когда содержимое одного поля влияет на требования, предъявляемые к  какому-то другому полю. Рассмотрим такую ситуацию на примере.
&lt;/p&gt;
&lt;p&gt;
Скажем, при вводе параметров почтового отправления пользователям по желанию предоставляется возможность где-то зарегистрироваться. Изъявить такое желание можно, заполнив необязательное поле для пароля (&lt;span class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;password&amp;quot;&lt;/span&gt; ...&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;), при этом в качестве логина будет использован email; если пароль будет указан, а email — нет, это следует воспринимать как ошибку.
&lt;/p&gt;
&lt;p&gt;
Это вносит в логику проверки некоторые изменения. Набор обязательных полей нужно в общем случае оставить неизменным, но если заполнено поле password — провести некоторые дополнительные проверки.
Вот как в таком случае будут выглядеть инструкции для поля password:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'password'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'&amp;gt;&amp;gt;'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'email'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Для регистрации введите адрес e-mail. (Если не хотите регистрироваться — просто оставьте поле &amp;quot;Пароль&amp;quot; пустым.)'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Рассмотрим этот код подробнее.
&lt;/p&gt;
&lt;p&gt;
Корневая инструкция представляет собой обычную проверку на заполненность. Однако она записана в развернутом виде и при этом элемент &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'text'&lt;/span&gt;&lt;/span&gt; у этой инструкции отсутствует. Поэтому если эта проверка и потерпит неудачу (как это случится при отправке пустого пароля), никакой ошибки все равно зарегистрировано не будет.
&lt;/p&gt;
&lt;p&gt;
Зачем же вообще тогда нужна такая инструкция? Ради элемента &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'&amp;gt;&amp;gt;'&lt;/span&gt;&lt;/span&gt;. Он представляет собой обычный список инструкций (и в него можно включать любые поля), которые выполняются только в том случае, если соответствующая корневая проверка пройдёт успешно (то есть, этот список является антагонистом ошибки). Буквально происходит следующее: те же самые поля независимо проверяются дополнительно с использованием массива &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'&amp;gt;&amp;gt;'&lt;/span&gt;&lt;/span&gt; в качестве набора инструкций, а выявленные ошибки дописываются к уже имеющимся&lt;sup&gt;&lt;a name=&quot;ftnref-4&quot; href=&quot;#ftn-4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;
&lt;p&gt;
Предположим теперь, что в случае ввода пароля нужно не только проверить email, но и установить ограничение на длину пароля. Например, чтобы он был не короче трёх символов.
&lt;/p&gt;
&lt;p&gt;
Это ограничение легко выразить с помощью регулярного выражения: &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'/.{3,}/'&lt;/span&gt;&lt;/span&gt;. Иметь эту инструкцию корневой, однако, нельзя (это обязало бы вводить пароль). Выйти из положения можно, поместив её в компанию к вложенной проверке email:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'password'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'&amp;gt;&amp;gt;'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'email'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Для регистрации введите адрес e-mail. ...'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'password'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'/.{3,}/'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Пароль должен быть не короче трёх символов.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Получается, что среди вложенных инструкций для поля password есть таковые для него самого же. Чтобы не писать название поля повторно, есть специальный ключ &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'/^R/'&lt;/span&gt;&lt;/span&gt;. С его помощью ту же самую инструкцию можно записать так:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'password'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'&amp;gt;&amp;gt;'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'email'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Для регистрации введите адрес e-mail. ...'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'^R'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// указывает на password&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'/.{3,}/'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Пароль должен быть не короче трёх символов.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;h2&gt;&lt;a name=&quot;files&quot;&gt;&lt;/a&gt;Проверка файлов&lt;/h2&gt;
&lt;p&gt;
Для файловых полей используются те же самые проверки, что и для обычных, однако они применяются уже не к собственно содержимому поля, а к массиву $_FILES, поэтому инструкции для файловых полей должны иметь специальную структуру.
&lt;p&gt;
Рассмотрим в качестве примера следующую HTML-форму:
&lt;/p&gt;
&lt;div class=&quot;code html4strict&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;form&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;method&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;POST&amp;quot;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;enctype&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;multipart/form-data&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;file&amp;quot;&lt;/span&gt; &lt;span class=&quot;kw3&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;st0&quot;&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&lt;span class=&quot;sc2&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Массив $_FILES для такой формы в случае успешной загрузки файла будет иметь примерно вот такой вид:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;Array&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;photo&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;Array&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;name&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; =&amp;gt; britney 100x100.jpg&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;type&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; =&amp;gt; image/jpeg&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;tmp_name&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; =&amp;gt; /tmp/php1AD.tmp&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;error&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;size&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;2752&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Предположим, нужно проверить, чтобы загруженный файл являлся изображением в формате JPEG или PNG и не превышал по размеру 1 Мб. Код для таких проверок будет выглядить следующим образом (инструкции поля weight приводятся для сравнения):
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$check_cfg&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'photo'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'name'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'/&lt;span class=&quot;es0&quot;&gt;\.&lt;/span&gt;(jpe?g|png)$/i'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Файл должен быть в формате JPEG или GIF.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// Для такой проверки можно было использовать и type: &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// принципиальной разницы нет, &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// т.к. type генерируется сервером на основе расширения файла.&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'size'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'&amp;lt; '&lt;/span&gt; . &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1024&lt;/span&gt; * &lt;span class=&quot;nu0&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Файл слишком большой, максимум - 1 Мб.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'weight'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Укажите примерный вес отправления.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'&amp;gt;= 0.2'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Минимальный регистрируемый вес отправления — 0.2 кг'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'&amp;lt; 10'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Отправления тяжелее 10 кг не принимаются.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$errors&lt;/span&gt; = check_form_errors&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$check_cfg&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$_POST&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$_FILES&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Чтобы сделать загрузку файла обязательной, в список инструкций нужно добавить элемент &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt;&lt;/span&gt;:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'photo'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Нужно загрузить файл.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'name'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'/&lt;span class=&quot;es0&quot;&gt;\.&lt;/span&gt;(jpe?g|png)$/i'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Файл должен быть в формате JPEG или PNG.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// Для такой проверки можно было использовать и type &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// принципиальной разницы нет, т.к. элемент type&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// генерируется сервером на основе расширения файла.&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'size'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'&amp;lt; '&lt;/span&gt; . &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1024&lt;/span&gt; * &lt;span class=&quot;nu0&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Файл {*name*} слишком большой, максимум - 1 Мб.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// Метка {*name*} заменится на исходное имя загруженного файла &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Если проверка на загрузку как таковую является единственной, инструкцию для поля можно записывать в сокращенной форме:&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'photo'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Нужно загрузить файл.'&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Анализ собственно содержимого файла, если есть такая необходимость, следует реализовывать через &lt;a href=&quot;#functions&quot;&gt;проверки с помощью сторонних функций&lt;/a&gt; на основе ключа tmp_name.
&lt;/p&gt;
&lt;p&gt;
Отдельного рассмотрения заслуживает детальная обработка ошибок состояния загрузки файла. Информация о состоянии загрузки содержится в элементе &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'error'&lt;/span&gt;&lt;/span&gt; в виде числового кода. &lt;a href=&quot;http://php.net/manual/ru/features.file-upload.errors.php&quot; target=&quot;_blank&quot;&gt;Набор этих кодов&lt;/a&gt; фиксирован и довольно невелик, поэтому в функцию включены стандартные сообщения об ошибках для некоторых из этих случаев:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;UPLOAD_ERR_NO_FILE (4): &lt;i&gt;&quot;Не выбран файл для загрузки.&quot;&lt;/i&gt;&lt;/li&gt;
	&lt;li&gt;UPLOAD_ERR_INI_SIZE (1): &lt;i&gt;&quot;Размер файла {*name*} не должен превышать Vб&quot;&lt;/i&gt; (где V = &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;ini_get&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'upload_max_filesize'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;)&lt;/li&gt;
	&lt;li&gt;Остальные: &lt;i&gt;&quot;При загрузке файла {*name*} возникли технические проблемы (код ошибки: {*error*}).&quot;&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Если сообщения, относящиеся к тем или иным ошибкам загрузки, требуется настроить, в инструкции проверок нужно включить массив &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'error'&lt;/span&gt;&lt;/span&gt;&lt;sup&gt;&lt;a name=&quot;ftnref-5&quot; href=&quot;#ftn-5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'photo'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'error'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; UPLOAD_ERR_NO_FILE =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Все-таки нужно загрузить файл.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; UPLOAD_ERR_CANT_WRITE =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Файл загрузить не получилось — наверное, на сервере кончилось место.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// Коды, для которых тексты сообщений об ошибках не указаны,&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// будут обработаны с использованием стандартных сообщений&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Если стандартные сообщения хочется использовать для всех ошибок загрузки, включая отсутствие файла, вместо инструкции &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt;&lt;/span&gt; следует указать  &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'error'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw2&quot;&gt;TRUE&lt;/span&gt;&lt;/span&gt;.
&lt;/p&gt;
&lt;p&gt;
Следует отметить, что если при загрузке файла возникли какие-либо сбои (код ошибки отличается от UPLOAD_ERR_OK), никакие инструкции, кроме собственно проверки состояния загрузки (&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt;&lt;/span&gt; и &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'error'&lt;/span&gt;&lt;/span&gt;), не исполняются.
&lt;/p&gt;
&lt;h2&gt;Проверка изображений&lt;/h2&gt;
&lt;p&gt;
Если предполагается загрузка изображения, можно выполнить ряд проверок некоторых его свойств, используя для этого специальный тип инструкций файлового поля. Это обычные инструкции, которые будут анализировать данные, полученные с помощью функции &lt;a href=&quot;http://php.net/getimagesize&quot; target=&quot;_blank&quot;&gt;getimagesize()&lt;/a&gt;. В результате своей работы она возвращает массив следующего вида:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;Array&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;450&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;675&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; =&amp;gt; width=&lt;span class=&quot;st0&quot;&gt;&amp;quot;450&amp;quot;&lt;/span&gt; height=&lt;span class=&quot;st0&quot;&gt;&amp;quot;675&amp;quot;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;bits&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;8&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;channels&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;3&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;mime&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; =&amp;gt; image/jpeg&lt;br /&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Предположим, нужно убедиться, что изображение нужного типа, и, кроме того, ограничить его максимальные размеры форматом 2048х1536.
Также
&lt;/p&gt;
&lt;p&gt;
Чтобы выполнить все эти проверки, нужно включить в инструкции для файлового поля специальный элемент — &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'image'&lt;/span&gt;&lt;/span&gt;:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'photo'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'image'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Файл &amp;quot;{*name*}&amp;quot; не является изображением или поврежден.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'mime'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'/jpeg|png/'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Изображение должно быть в формате JPEG или PNG.'&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// Нужно сказать, что getimagesize() устанавливает mime-type файла&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// на основе анализа его содержимого (определяется верно даже &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// при неправильном расширении), поэтому для проверки типа изображения &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// лучше использовать результат работы getimagesize(), &lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;co1&quot;&gt;// а не содержимое $_FILES.&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'width'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'&amp;lt;= 2048'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Ширина изображения не должна превышать 2048 px.'&lt;/span&gt;, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'height'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;st0&quot;&gt;'&amp;lt;= 1536'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Высота изображения не должна превышать 1536 px.'&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;
Инструкции по остальным свойствам (например, &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'bits'&lt;/span&gt;&lt;/span&gt; или &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'channels'&lt;/span&gt;&lt;/span&gt;), при необходимости, составляются по тем же принципам.
&lt;/p&gt;
&lt;p&gt;
Ключи &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'width'&lt;/span&gt;&lt;/span&gt; и &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'height'&lt;/span&gt;&lt;/span&gt; используются в качестве псевдонимов для ключей &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;/span&gt; и &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;/span&gt; исходного массива от getimagesize().
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;notes&quot;&gt;&lt;/a&gt;Примечания&lt;/h2&gt;
&lt;p&gt;
Дубликаты сообщений об ошибках перед завершением работы функции удаляются (с помощью &lt;a href=&quot;http://php.net/array_unique&quot; target=&quot;_blank&quot;&gt;array_unique&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
Если содержимое поля формы является массивом, указанные проверки будут применены к каждому из его элементов.
&lt;/p&gt;
&lt;p&gt;
Для генерации HTML-кода форм разработан &lt;a href=&quot;http://webew.ru/articles/5239.webew&quot; title=&quot;Генерация HTML-кода форм с помощью языка PHP&quot;&gt;специальный инструментарий&lt;/a&gt;.
&lt;/p&gt;
&lt;div class=&quot;footnote&quot;&gt;
	&lt;p&gt;
		1.
		&lt;a name=&quot;ftn-1&quot; href=&quot;#ftnref-1&quot; title=&quot;вернуться к тексту&quot;&gt;▲&lt;/a&gt;
		Такие проверки лучше составлять, сначала продумав допустимый диапазон величин поля и выразив его в виде неравенства, а затем составить текст сообщения для случая, когда величина выходит за границы этого диапазона. Как правило, неравенство и текст должны противоречить друг другу (как это имеет место в примере: &lt;i&gt;&amp;quot;&lt;b&gt;&amp;lt;=&lt;/b&gt; 10&amp;quot; — &amp;quot;... &lt;b&gt;тяжелее&lt;/b&gt; 10 кг ...&amp;quot;&lt;/i&gt;, и т.п.).
	&lt;/p&gt;
	&lt;p&gt;
		2.
		&lt;a name=&quot;ftn-2&quot; href=&quot;#ftnref-2&quot; title=&quot;вернуться к тексту&quot;&gt;▲&lt;/a&gt;
		C помощью функции &lt;a href=&quot;http://php.net/trim&quot; target=&quot;_blank&quot;&gt;trim()&lt;/a&gt;.
	&lt;/p&gt;
	&lt;p&gt;
		3.
		&lt;a name=&quot;ftn-3&quot; href=&quot;#ftnref-3&quot; title=&quot;вернуться к тексту&quot;&gt;▲&lt;/a&gt;
		При этом позиция, на которой среди инструкций находится '*', значения не имеет (то есть, её можно ставить и не первой, хотя это будет менее наглядно).
	&lt;/p&gt;
	&lt;p&gt;
		4.
		&lt;a name=&quot;ftn-4&quot; href=&quot;#ftnref-4&quot; title=&quot;вернуться к тексту&quot;&gt;▲&lt;/a&gt;
		Никаких ограничений на вложенные инструкции по сравнению с корневыми нет. Уровень вложенности не ограничен.
	&lt;/p&gt;
	&lt;p&gt;
		5.
		&lt;a name=&quot;ftn-5&quot; href=&quot;#ftnref-5&quot; title=&quot;вернуться к тексту&quot;&gt;▲&lt;/a&gt;
		Вообще говоря, инструкция &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'текст'&lt;/span&gt;&lt;/span&gt; для файлового поля равносильна инструкции
		&lt;br&gt;
		&lt;br&gt;
		&lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'error'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; UPLOAD_ERR_NO_FILE =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'текст'&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/span&gt;
		&lt;br&gt;
		&lt;br&gt;
		с той лишь разницей, что &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'*'&lt;/span&gt;&lt;/span&gt;, в отличие от &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;st0&quot;&gt;'error'&lt;/span&gt;&lt;/span&gt;, сработает и в том случае, если поле вообще отсутствует в форме (и — как следствие — отсутствует соответствующий элемент в массиве $_FILES).
	&lt;/p&gt;
&lt;/div&gt;</description>
</item>
<item>
  <title>PHP: критика перехода с оригинального API MySQL на mysqli и PDO</title>
  <link>http://webew.ru/articles/4920.webew</link>
  <guid>http://webew.ru/articles/4920.webew</guid>
  <pubDate>Fri, 29 Mar 2013 17:32:34 +0400</pubDate>
  <description>	&lt;p&gt;
		Оригинальный API MySQL (функции mysql_*() — например, mysql_query() и пр.) с версии PHP 5.5.0 &lt;a href=&quot;http://www.php.net/manual/en/mysqlinfo.api.choosing.php&quot; &gt;объявлен устаревшим&lt;/a&gt;. Вместо него разработчики PHP рекомендуют использовать &lt;a href=&quot;http://www.php.net/manual/ru/book.mysqli.php&quot;&gt;модуль mysqli&lt;/a&gt; или &lt;a href=&quot;http://www.php.net/manual/en/ref.pdo-mysql.php&quot; &gt;объекты данных PHP (PDO)&lt;/a&gt;. Эти средства обладают расширенным по сравнению с традиционным API функционалом, но действительно ли они удобнее в повседневной практике?
	&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;mysqli&quot;&gt;&lt;/a&gt;mysqli&lt;/h2&gt;
	&lt;p&gt;
		mysqli — &amp;quot;MySQL improved extension&amp;quot; (&amp;quot;улучшенный модуль MySQL&amp;quot;) — прямой наследник оригинального API MySQL, обладающий более широкими возможностями. Чтобы почувствовать разницу, достаточно посмотреть на &lt;a href=&quot;http://www.php.net/manual/en/mysqli.summary.php&quot; &gt;список его методов&lt;/a&gt; и сравнить с &lt;a href=&quot;http://www.php.net/manual/ru/ref.mysql.php&quot; &gt;таковым оригинального модуля&lt;/a&gt;. Однако нужно отметить, что отличие в реальных возможностях на самом деле только одно: &lt;a href=&quot;http://www.php.net/manual/en/mysqli.multi-query.php&quot;&gt;mysqli имеет возможность отправки множественных запросов&lt;/a&gt;&lt;a name=&quot;ftnref-1&quot; href=&quot;#ftn-1&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. Хотя иметь такую возможность и удобно, на практике её наличие ощутимой роли не играет&lt;a name=&quot;ftnref-2&quot; href=&quot;#ftn-2&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;.
	&lt;/p&gt;
	&lt;p&gt;
		Другими словами, разницы в реальных возможностях обычного и улучшенного модулей практически нет. Зато есть  разница в интерфейсе. Рассмотрим, как  в простейшем случае выглядит самая обычная операция — установление соединения с сервером MySQL и выполнение запроса:
	&lt;/p&gt;
	&lt;p&gt;
		&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// оригинальный модуль&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kw3&quot;&gt;mysql_connect&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'host'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'user'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'password'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw3&quot;&gt;mysql_query&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;SELECT 1&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// улучшенный модуль, процедурный интерфейс&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$mysqli&lt;/span&gt; = mysqli_connect&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'host'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'user'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'password'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
mysqli_query&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$mysqli&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;&amp;quot;SELECT 1&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// улучшенный модуль, объектный интерфейс&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$mysqli&lt;/span&gt; = &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; mysqli&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$host&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$user&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$password&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$mysqli&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;SELECT 1&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/div&gt;
	&lt;/p&gt;
	&lt;p&gt;
		Здесь важно заметить, что функция mysql_query() не требует передавать в явном виде указатель на соединение (хотя и позволяет это делать). В подавляющем большинстве случаев для работы требуется только одно соединение с MySQL, и, однажды установив его, вполне удобно и естественно просто вызывать mysql-функции, не ссылаясь на соединение в явном виде каждый раз.
	&lt;/p&gt;
	&lt;p&gt;
		Функция же mysqli_query(), напротив, требует передавать объект, указывающий на соединение. Этот объект потребуется во всех местах, где нужно будет делать запрос. Это означает, что в коде с локальной областью видимости — функциях и классах — придется либо заводить глобальную переменную, либо передавать этот объект явно.
	&lt;/p&gt;
	&lt;p&gt;
		Это, казалось бы, небольшое отличие на практике не только приводит к необходимости писать более длинный код, но и осложняет миграцию с оригинального модуля на улучшенный из-за необходимости вносить в код изменения.
	&lt;/p&gt;
	&lt;p&gt;
		Резюмируя сказанное, приходится констатировать, что на практике модуль mysqli не обладает какой-то дополнительной полезностью по сравнению с оригинальным. Пользоваться же им менее удобно.
	&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;pdo&quot;&gt;&lt;/a&gt;PDO&lt;/h2&gt;
	&lt;p&gt;
		PHP Data Object (Объекты данных PHP) — расширение языка, определяющее абстрактный интерфейс доступа к базам данных (это означает, что одни и те же методы PDO могут использоваться для разных СУБД).
	&lt;/p&gt;
	&lt;p&gt;
		На практике реально ощутимым отличием PDO от других интерфейсов к MySQL является возможность легко делать следующие две операции:
	&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;вставку в запрос параметров с экранированием&lt;/li&gt;
		&lt;li&gt;получение результата запроса в виде ассоциативного массива&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;
		Работа с MySQL, в основном, и заключается именно в этих двух вещах, поэтому многие разработчики останавливают свой выбор на PDO.
	&lt;/p&gt;
	&lt;p&gt;
		Однако есть один нюанс. Рассмотрим, как в самом простом случае средствами PDO выполняется запрос:
	&lt;/p&gt;
	&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$DBH&lt;/span&gt; = &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; PDO&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'mysql:host=...;dbname=...'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'user'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'password'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;co1&quot;&gt;// соединяемся с БД&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$DBH&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;prepare&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;SELECT 1&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;co1&quot;&gt;// готовим запрос&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$query&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span class=&quot;co1&quot;&gt;// выполняем запрос&lt;/span&gt;&lt;/div&gt;
	&lt;p&gt;
		Важно отметить, что для отправки запроса требуется вызывать не один метод, а два — &lt;a href=&quot;http://www.php.net/manual/ru/pdo.prepare.php&quot;&gt;prepare()&lt;/a&gt;, а затем &lt;a href=&quot;http://php.net/manual/en/pdostatement.execute.php&quot;&gt;execute()&lt;/a&gt;. На уровне механизма СУБД в данном случае задействуются т.н. &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.6/en/sql-syntax-prepared-statements.html&quot;&gt;prepared statements&lt;/a&gt; — специальный инструмент СУБД, позволяющий ускорить последовательное выполнение повторяющихся запросов, построенных по одному и тому же шаблону.
	&lt;/p&gt;
	&lt;/p&gt;
		Вместе с тем, на практике идущие подряд  однотипные запросы встречаются довольно редко. Напротив, обычно запросы разные, и это полностью нивелирует положительный эффект от предварительного разбора.
		Более того, в конечном итоге вместо одного запроса к MySQL делается два, в результате чего схема с prepare() и execute() оказывается даже медленнее обычного одиночного запроса.
	&lt;/p&gt;
	&lt;p&gt;
		PDO позволяет выполнить запрос и напрямую — для этого предназначен метод &lt;a href=&quot;http://www.php.net/manual/ru/pdo.query.php&quot;&gt;query()&lt;/a&gt;. Однако при использовании этого метода вставку в запрос параметров и их экранирование приходится проводить вручную, поэтому query() не пользуется популярностью и разработчики предпочитают связку из prepare() и execute() в любом случае, потому что это удобнее.
	&lt;/p&gt;
	&lt;p&gt;
		Следует также подчеркнуть, что при использовании PDO (как и в случае с mysqli) есть необходимость заводить объект, который в областях видимости функций и классов недоступен.
	&lt;/p&gt;
	&lt;p&gt;
		Резюмируя сказанное, нужно отметить, что по сравнению с другими модулями PDO предоставляет несколько более удобный функционал, однако реализация его выполнена неоптимально. Кроме того, высокий уровень абстракции интерфейса плохо сказывается на осведомлённости разработчиков о происходящем на стороне MySQL-сервера.
	&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;solution&quot;&gt;&lt;/a&gt;Что делать?&lt;/h2&gt;
	&lt;p&gt;
		Одним из решений всех вышеперечисленных проблем является &lt;a href=&quot;http://webew.ru/f/CANrZGYd.php&quot;&gt;библиотека удобных функций MySQL&lt;/a&gt;, при разработке которой основной целью было сделать программирование самых распространенных операций при работе с MySQL (таких как сохранение результата запроса в виде ассоциативного массива, обработка ошибок, подстановка массива в запрос) максимально удобным. Вот несколько примеров:
	&lt;/p&gt;
	&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// если в глобальной области видимости есть переменная $mysqli,&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// библиотека будет пользоваться инструментами mysqli,&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// в противном случае - оригинального модуля MySQL&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// включаем mysqli&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$mysqli&lt;/span&gt; = mysqli_connect&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;...&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// простая отправка запроса&lt;/span&gt;&lt;br /&gt;
mysql_q&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;TRUNCATE sometable&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// получение результата скалярного (один столбец, одна строка) запроса&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$now&lt;/span&gt; = mysql_getcell&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;SELECT NOW()&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// получение строки таблицы:&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$row&lt;/span&gt; = mysql_getrow&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; SELECT * &lt;br /&gt;
&amp;nbsp; &amp;nbsp; FROM watches&lt;br /&gt;
&amp;nbsp; &amp;nbsp; WHERE id = 1052&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// получение столбца в виде одномерного массива:&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$ids&lt;/span&gt; = mysql_getcolumn&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; SELECT id&lt;br /&gt;
&amp;nbsp; &amp;nbsp; FROM watches&lt;br /&gt;
&amp;nbsp; &amp;nbsp; WHERE mark = 'Edox' AND price &amp;gt; 5000&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// получение записей таблицы с подстановкой в запрос параметров:&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$sql&lt;/span&gt; = &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; SELECT *&lt;br /&gt;
&amp;nbsp; &amp;nbsp; FROM watches&lt;br /&gt;
&amp;nbsp; &amp;nbsp; WHERE mark = :mark AND price &amp;gt; :price&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$params&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'mark'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;st0&quot;&gt;'Edox'&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;'price'&lt;/span&gt; =&amp;gt; &lt;span class=&quot;nu0&quot;&gt;5000&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$data&lt;/span&gt; = mysql_gettable&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$sql&lt;/span&gt;, &lt;span class=&quot;kw2&quot;&gt;FALSE&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$params&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// подстановку можно делать во всех вышеперечисленных функциях&lt;/span&gt;&lt;/div&gt;
	&lt;p&gt;
	Подробнее о библиотеке можно прочитать в &lt;a href=&quot;http://webew.ru/articles/3237.webew&quot;&gt;соответствующей статье&lt;/a&gt;.
	&lt;/p&gt;
&lt;div class=&quot;footnote&quot;&gt;
	&lt;p&gt;
		1.
		&lt;a title=&quot;вернуться к тексту&quot; href=&quot;#ftnref-1&quot; name=&quot;ftn-1&quot;&gt;&amp;#x25b2;&lt;/a&gt;
		Работу с транзакциями, хранимыми процедурами и прочим, заявленным в документации как отличия между модулями, на самом деле можно реализовывать с помощью собственно SQL-запросов: например, вместо &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$mysqli&lt;/span&gt;-&amp;gt;&lt;span class=&quot;me1&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt; писать &lt;span class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;mysql_query&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;COMMIT&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;, и т.п.
	&lt;/p&gt;
	&lt;p&gt;
		2.
		&lt;a title=&quot;вернуться к тексту&quot; href=&quot;#ftnref-2&quot; name=&quot;ftn-2&quot;&gt;&amp;#x25b2;&lt;/a&gt;
		Разница в производительности множественного запроса и соответствующего количества одиночных сводится к затратам на отправку запроса из PHP, которые по сравнению с затратами на собственно их выполнение механизмом СУБД как правило ничтожно малы. Кроме того, ситуация, когда запросы следуют подряд без необходимости промежуточной обработки результатов, является довольно редкой.
	&lt;/p&gt;
&lt;/div&gt;</description>
</item>
<item>
  <title>Архитектурная концепция программирования при работе со списками в веб-приложениях на основе PHP и MySQL</title>
  <link>http://webew.ru/articles/4856.webew</link>
  <guid>http://webew.ru/articles/4856.webew</guid>
  <pubDate>Thu, 28 Feb 2013 15:04:58 +0400</pubDate>
  <description>&lt;p&gt;
В статье излагается подход, позволяющий оптимизировать производительность запросов MySQL, а также облегчить написание кода на PHP с использованием специально разработанной для этого библиотеки.
&lt;/p&gt;
&lt;h2&gt;Оптимизация запросов MySQL&lt;/h2&gt;
&lt;p&gt;
Один из подходов к оптимизации запросов, используемых для получения данных списков, заключается в разбиении таких запросов на две части:
&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Получение списка идентификаторов.&lt;/li&gt;
	&lt;li&gt;Получение собственно данных.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Отчего так получается быстрее? Рассмотрим этот вопрос подробнее.
&lt;/p&gt;
&lt;p&gt;
Как правило, списки составляются на основании каких-то условий (к примеру, показываются не все новости, а лишь несколько последних; не все товары, а только лежащие в определенном ценовом диапазоне и т.п.), при этом часто задействуются связи с другими сущностями (например, товары принадлежат к определенной категории, у новостей или статей может быть автор и др.). С точки зрения СУБД это означает, что требуется запрос типа JOIN с WHERE, ORDER BY (а часто - также GROUP BY) и LIMIT. Обычно такие запросы выполняются медленно и нередко становятся серьезной проблемой&lt;sup&gt;&lt;a name=&quot;ftnref-1&quot; href=&quot;#ftn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. В качестве примера возьмем запрос, используемый в CMS Wordpress:
&lt;/p&gt;
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; * &lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; wp_posts&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;LEFT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;JOIN&lt;/span&gt; wp_post2cat &lt;span class=&quot;kw1&quot;&gt;ON&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;wp_posts.ID = wp_post2cat.post_id&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;LEFT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;JOIN&lt;/span&gt; wp_categories &lt;span class=&quot;kw1&quot;&gt;ON&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;wp_post2cat.category_id = wp_categories.cat_ID&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;=&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;category_id = &lt;span class=&quot;st0&quot;&gt;'1'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;AND&lt;/span&gt; post_date_gmt &amp;lt;= &lt;span class=&quot;st0&quot;&gt;'2008-09-12 00:15:59'&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;post_status = &lt;span class=&quot;st0&quot;&gt;'publish'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;AND&lt;/span&gt; post_status != &lt;span class=&quot;st0&quot;&gt;'attachment'&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;GROUP&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; wp_posts.ID&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; post_date &lt;span class=&quot;kw1&quot;&gt;DESC&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;9&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;3&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Причина медленного его выполнения лежит в особенностях механизма работы MySQL и заключается в следующем. Сложность условий выборки не позволяет использовать для сортировки индексы, поэтому MySQL потребуется создать временную таблицу, содержащую все перечисленные в запросе колонки, которую затем отсортировать и выбрать указанное число записей. Поскольку такая временная таблица будет велика, эта операция будет происходить медленно (это усугубится еще сильнее, если временная таблица не поместится в оперативную память). &lt;em&gt;Решающее значение здесь имеет именно общая длина колонок&lt;/em&gt;: чем длиннее строка таблицы, тем больше ресурсов потребуется на то, чтобы такие длинные строки переставить в нужном порядке.
&lt;/p&gt;
&lt;p&gt;
Следует отметить также, что, по сравнению с общим количеством обрабатываемых записей конечное результирующее их число невелико. Получается, что б&amp;#769;ольшая часть работы по выборке содержимого ячеек и сортировке получившихся в результате длинных записей фактически делается впустую.
&lt;/p&gt;
&lt;p&gt;
Если в части SELECT запроса оставить только идентификаторы записей, а среди таблиц оставить только те, что необходимы для проверки условий (что тоже немаловажно, т.к. позвляет избавиться от лишних JOIN), запрос значительно ускорится.
&lt;/p&gt;
&lt;p&gt;
Вот как это будет выглядеть на практике при использовании языка PHP:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// 1.1. Уберем из запроса все колонки, кроме ID, а также лишние таблицы:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$sql&lt;/span&gt; = &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; SELECT wp_posts.ID &lt;br /&gt;
&amp;nbsp; &amp;nbsp; FROM wp_posts&lt;br /&gt;
&amp;nbsp; &amp;nbsp; LEFT JOIN wp_post2cat ON (wp_posts.ID = wp_post2cat.post_id)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; WHERE (category_id = '1')&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; AND post_date_gmt &amp;lt;= '2008-09-12 00:15:59'&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; AND (post_status = 'publish')&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; AND post_status != 'attachment'&lt;br /&gt;
&amp;nbsp; &amp;nbsp; ORDER BY post_date DESC&lt;br /&gt;
&amp;nbsp; &amp;nbsp; LIMIT 9, 3;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// 1.2. Теперь получим список идентификаторов:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$ids&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$result&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;mysql_query&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$sql&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$row&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;mysql_fetch_assoc&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; !== &lt;span class=&quot;kw2&quot;&gt;FALSE&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$ids&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'ID'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;
Теперь нужно получить непосредственно данные для этих трех записей, сохранив при этом порядок сортировки:
&lt;/p&gt;
&lt;div class=&quot;code php&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// 2.1. Получаем данные в неотсортированном виде:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$sql&lt;/span&gt; = &lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; SELECT *&lt;br /&gt;
&amp;nbsp; &amp;nbsp; FROM wp_posts&lt;br /&gt;
&amp;nbsp; &amp;nbsp; LEFT JOIN wp_post2cat&lt;br /&gt;
&amp;nbsp; &amp;nbsp; LEFT JOIN wp_categories&lt;br /&gt;
&amp;nbsp; &amp;nbsp; WHERE wp_posts.ID IN (&amp;quot;&lt;/span&gt; . &lt;span class=&quot;kw3&quot;&gt;implode&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;,&amp;quot;&lt;/span&gt;, &lt;span class=&quot;re0&quot;&gt;$ids&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; . &lt;span class=&quot;st0&quot;&gt;&amp;quot;)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;quot;&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$data_raw&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$result&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;mysql_query&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$sql&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$row&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;mysql_fetch_assoc&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; !== &lt;span class=&quot;kw2&quot;&gt;FALSE&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$data_raw&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'ID'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$row&lt;/span&gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;co1&quot;&gt;// 2.2. Восстанавливаем порядок сортировки:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;re0&quot;&gt;$data_final&lt;/span&gt; = &lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$ids&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;re0&quot;&gt;$data_final&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span class=&quot;re0&quot;&gt;$data_raw&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp;&lt;/div&gt;
&lt;p&gt;
Надо сказать, что выигрыш от такого разбиения достигается не всегда, и можно привести немало примеров, когда запросы выполняются быстро и в своем исходном виде. Но быстрые запросы выполнятся быстро в обоих случаях (дополнительная операция выборки по первичному ключу занимает очень мало времени), медленные же значительно ускорятся, поэтому использование разбиения запроса на две части в качестве единого подхода оправдано.
&lt;/p&gt;
&lt;h2&gt;&lt;a name=&quot;ORM&quot;&gt;&lt;/a&gt;Библиотека для работы со списками&lt;/h2&gt;
&lt;p&gt;
Описанный подход является одним из основных принципов, лежащих в основе универсальной библиотеки для работы со списками, которая реализует объектно-реляционное отображение. Библиотеке посвящена  &lt;a href=&quot;http://webew.ru/articles/5096.webew&quot;&gt;отдельная статья&lt;/a&gt;.
&lt;/p&gt;
&lt;div class=&quot;footnote&quot;&gt;
	&lt;p&gt;
		1.
		&lt;a name=&quot;ftn-1&quot; href=&quot;#ftnref-1&quot; title=&quot;вернуться к тексту&quot;&gt;&amp;#x25b2;&lt;/a&gt;
		По данным &lt;a href=&quot;http://online.webew.ru/mysqlpt&quot;&gt;курса по оптимизации производительности MySQL&lt;/a&gt;, запросы такого типа создают б&amp;#769;ольшую часть нагрузки на сервера MySQL в Рунете, а их оптимизация решает около 50% всех проблем производительности. См. также &lt;a href=&quot;http://sqlinfo.ru/a/i/rubtsov_mysqlbot.ppt&quot;&gt;&amp;quot;Ботанический определитель&amp;quot; Григория Рубцова&lt;/a&gt;.
	&lt;/p&gt;
&lt;/div&gt;</description>
</item>
<item>
  <title>Конференция по управлению WhaleRider 2012, Москва 24-25 сентября 2012</title>
  <link>http://webew.ru/posts/4587.webew</link>
  <guid>http://webew.ru/posts/4587.webew</guid>
  <pubDate>Sun, 16 Sep 2012 22:41:50 +0400</pubDate>
  <description>Уважаемые читатели webew!&lt;br /&gt;
&lt;br /&gt;
Сообщаем вам о ежегодной профессиональной конференции по управлению &lt;a href=&quot;http://www.whalerider.ru/?partner=sqlinfo&quot;&gt;Whale Rider&lt;/a&gt;, которая пройдет 24 и 25 сентября в Москве.&lt;br /&gt;
&lt;br /&gt;
Интернет-проекты сложны и требуют вовлечения большого количества разноплановых специалистов, которые мало что понимают в работе друг друга. Ключевая проблема отрасли - неумение работать слаженно, всем вместе. В качестве ключевой идеи конференции предлагается интеграция управленцев всех стадий жизненного цикла Интернет-продукта. Давайте рассмотрим весь жизненный цикл производства программного продукта, что одновременно и будет программой конференции Whale Rider 2012:&lt;br /&gt;
&lt;br /&gt;
1. Что у нас в самом начале? Идея. И ничего больше. Может быть, капельку надежды. Отлично! Сюда мы приглашаем всех наших успешных бизнесменов и стартаперов со своими Success Story и &amp;quot;Ребята, мне повезло!&amp;quot;. Мотивация и прочие моменты озарения, а также рассказы о том, &amp;quot;как сделать, чтобы и вы заработали свой миллион!&amp;quot;; Дальше можно осмысленно переходить к &lt;br /&gt;
&lt;br /&gt;
2. Анализу. Почему заказчик получает в итоге не всегда то, что хочет? Как проверить идею и понять, а выстрелит ли проект? Какие фичи нужно делать, а какие нет? С чего начать? В секцию приглашены руководители отделов анализа и (!) заказчики.&lt;br /&gt;
&lt;br /&gt;
3. Проектирование: как не увязнуть в дебрях размышлений и быстро выпустить продукт с нужным функционалом на рынок? Как показать инвесторам свою состоятельность и получить следующий транш на разработку? Как быстро проверить свои идеи, собрав на коленке прототип. Моделирование предметной области как способ синхронизации представления всех заинтересованных сторон о проблеме. Эта секция для руководителей отделов проектирования и юзабилити.&lt;br /&gt;
&lt;br /&gt;
4. Разработка. Как пасти котов? Во сколько обойдутся ошибки управления разработкой вашему продукту? Что мир знает кроме Agile и Водопада? Как организовать миссию на Марс: что сделали менеджеры проекта Curiosity, чтобы провести удаленную (действительно удаленную) перепрошивку программного обеспечения? Приглашены технические директора, руководители отделов разработки, ведущие специалисты, тимлиды и архитекторы.&lt;br /&gt;
&lt;br /&gt;
5. Тестирование и приемка. Вы, как заказчик, получили именно то, что хотели? На сцене руководители отделов тестирования и качества!&lt;br /&gt;
&lt;br /&gt;
6. Эксплуатация управление сложными программно-аппаратными комплексами. Снижение стоимости владения: нужно ли бежать за модой и уходить &amp;quot;в облака&amp;quot;? Кому верить: маркетологу с ролексом или админу в свитере? На эти и другие вопросы ответят руководители поддержки и эксплуатации.&lt;br /&gt;
&lt;br /&gt;
И, наконец, метауровень (уровень, &amp;quot;обволакивающий&amp;quot; жизненный цикл и встраивающий его в надсистемы: рынок, государство и прочие социальные институты) - организационный момент. Взаимодействие с рынком, государством, бизнесом. Налоги и прибыль. Как собрать, воспитать и удержать команду? Как исходя из целей продукта выбрать маркетинговую стратегию? Как заказчикам, со своими процессами и бизнес-целями, взаимодействовать с студиями и&lt;br /&gt;
командами-разработками? Продажи. Организация и схемы продаж.&lt;br /&gt;
&lt;br /&gt;
Выступить на секцию метауровня мы пригласили юристов, состоявшихся менеджеров продуктов и проектов, хороших продажников, директоров и гениальных маркетологов.&lt;br /&gt;
&lt;br /&gt;
Все вместе мы будем обсуждать жизнь продукта от зарождения идеи, проектирования и разработки до экплуатации, прибыли и... выхода на IPO.&lt;br /&gt;
&lt;br /&gt;
Читателям webew предоставляется скидка 10%. Для того, чтобы ею воспользоваться, введите SQLinfoCODE в заявку на формирование счета.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.whalerider.ru/?partner=sqlinfo&quot;&gt;До встречи на конференции.&lt;/a&gt;</description>
</item>
<item>
  <title>Highload++, Москва, 24-25 октября 2012</title>
  <link>http://webew.ru/posts/4492.webew</link>
  <guid>http://webew.ru/posts/4492.webew</guid>
  <pubDate>Sun, 15 Jul 2012 14:02:58 +0400</pubDate>
  <description>Объявлена конференция разработчиков высоконагруженных систем Highload++ 2012.&lt;br /&gt;
&lt;br /&gt;
См. наш &lt;a href=&quot;http://webew.ru/articles/3860.webew&quot;&gt;обзор Highload++ 2011&lt;/a&gt; и спешите зарегистрироваться на &lt;a href=&quot;http://www.highload.ru/&quot;&gt;официальном сайте&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Пока Программа только формируется, немного о примерах докладов и собрании Программного комитета HL++. Компания Мамба, 250М хитов в сутки, вполне себе хайлоад, представит целую серию докладов:&lt;br /&gt;
+ специализированный поиск примерно в 100 раз быстрее Сфинкса;&lt;br /&gt;
+ персистентный производительный брокер очередей;&lt;br /&gt;
+ правильная система деплоя (заметьте - не просто система деплоя, а правильная!);&lt;br /&gt;
+ i18n на больших проектах;&lt;br /&gt;
+ использование comet для реалтайм счетчиков под реально большой нагрузкой.&lt;br /&gt;
&lt;br /&gt;
Доклад Александра Короткова &amp;quot;Индексный поиск по регулярным выражениям&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Существует два основных подхода к выполнению поиска по регулярным выражениям с помощью индекса: &amp;quot;FREE indexing engine&amp;quot;, основанный на выделении из регулярного выражения непрерывных фрагментов текста, и метод разработанный для Google Code Search, осуществляющий рекурсивный анализ составных частей регулярного выражения, с целью выявления его атрибутов. В целом же оба этих подхода используют инвертированные индексы на основе k-грам (подстрок исходной строки длиной k) и различаются методом извлечения k-грам из исходного выражения для последующего сканирования.&lt;br /&gt;
&lt;br /&gt;
Данный доклад представляет новый метод извлечений k-грам из регулярного выражения, основанный не на анализе исходного регулярного выражения, а на преобразовании соответствующего конечного автомата. Предлагаемый подход позволяет осуществить более полное извлечение k-грам из регулярного выражения, что подтверждается примерами. Разработан патч к модулю pg_trgm СУБД PostgreSQL, реализующий данный подход.&lt;br /&gt;
&lt;br /&gt;
Все из нас используют индексы в СУБД, но редко кто понимает, как они работают. Именно это понимание и отличает highload-разработчика от просто разработчика.&lt;br /&gt;
&lt;br /&gt;
Алексей Тутубалин сделает доклад под кодовым названием &amp;quot;Используем современный процессор на 146%&amp;quot; про современное состояние параллельных вычислений. Приведем краткий конспект выступления:&lt;br /&gt;
&lt;br /&gt;
+ Векторные операции (SIMD: MMX, SSE, AVX). SIMD расшифровывается как single instruction, multiple data - одиночный поток команд, множественный поток данных. Что умеет, типы данных, виды операций. Требования к программам и алгоритмам, выравнивание данных. Быстродействие формальное и реальное. Кто сделает SIMD-код?&lt;br /&gt;
+ Многоядерные процессоры, многопроцессорные конфигурации. Сложно думать параллельно, сложно отлаживать (невоспроизводимые ситуации), data races, расход ресурсов на синхронизацию, проблемы с процессорными кэшами если потоки работают с одними/близкими адресами в памяти. Типичное современное использование:&lt;br /&gt;
   ++ Несколько/много изолированных процессов&lt;br /&gt;
   ++ Несколько/много потоков (threads), обрабатывающих независимые запросы&lt;br /&gt;
   ++ Сложные многопоточные программы, сильно связанные внутри себя&lt;br /&gt;
   ++ Data-parallel программы: пилим (большие) данные на (независимые) куски и обрабатываем: map-Reduce (всех видов), сортировка, точки синхронизации/reduce понятны, не требуется синхронизация в случайный момент, да еще и по внешнему событию. Data races маловероятны. Программа выглядит последовательной, а вычислительно-интенсивные места используют все ядра/CPU.&lt;br /&gt;
+ Параллельные языки программирования:&lt;br /&gt;
   ++ ISPC: интересует CPU-only, двойная буферизация болезненна, нет желания таскать большой рантайм вне программы.&lt;br /&gt;
   ++ OpenCL:  планируется/возможен перенос на GPU, рантайм не пугает, двойная буферизация не пугает.</description>
</item>
<item>
  <title>РИТ++ 2012. Репортаж с места событий.</title>
  <link>http://webew.ru/posts/4361.webew</link>
  <guid>http://webew.ru/posts/4361.webew</guid>
  <pubDate>Mon, 16 Apr 2012 21:02:54 +0400</pubDate>
  <description>2-3 апреля 2012 года в Москве прошла ежегодная конференция &lt;a href=&quot;http://ritconf.ru&quot;&gt;&amp;quot;Российские интернет-технологии 2012&amp;quot; (РИТ++)&lt;/a&gt;. Мероприятие впервые проходило в конференц-центре &lt;a href=&quot;http://digitaloctober.ru/&quot;&gt;Digital October&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Цифровой Октябрь&amp;quot; довольно сильно отличается от своего &lt;a href=&quot;http://info-space.ru&quot;&gt;предшественника&lt;/a&gt;, поэтому поначалу было немножко непривычно.&lt;br /&gt;
Едят в &amp;quot;Цифровом Октябре&amp;quot; в специальной зоне питания под названием &amp;quot;&lt;a href=&quot;http://digitaloctober.ru/progress-bar/menu&quot;&gt;Прогресс-бар&lt;/a&gt;&amp;quot;. Существенным плюсом являлась возможность сидеть во время приема пищи (в отличие от &amp;quot;Инфопространства&amp;quot;, где есть приходилось стоя). Это ведь самый настоящий бар, с длиннющей стойкой и стульями вдоль неё, а также с обычными столами и посадочными местами вокруг них. Так что усесться могло одновременно человек пятьдесят, не меньше. Имеются многочисленные экраны (включая один большой), по которым транслировались доклады.&lt;br /&gt;
Прогресс-бар весьма оригинально оформлен: стены украшают картины известных художников,  гармонично дополненные образчиками современных технологий (ноутбук Apple, &lt;a href=&quot;http://ru.wikipedia.org/wiki/AIBO&quot;&gt;робот-собака&lt;/a&gt; и др.; в общем, всё, что символизирует прогресс). &lt;br /&gt;
Но, пожалуй, самой выдающейся особенностью является стеклянный участок пола, под которым уходит вниз лифтовая шахта (дна не видно). Этот участок находится как раз перед туалетом (а второй туалет далеко и не все про него знают), причем стекло сделано во всю ширину коридора и обойти его нельзя - чтобы попасть в туалет, нужно непременно ступить на стеклянную поверхность и сделать несколько шагов над инфернальной бездной (шахта подсвечена красными лампами). После такой прогулки, например, людям с боязнью высоты идти в туалет может оказаться уже поздно. А для тех, кто считает себя особо смелыми, персонал Прогресс-бара уже давно разработал программу веселого розыгрыша: датчик движения и проигрывание звука трескающегося стекла.. (правда, наверняка эта инициатива застрянет в руководстве).&lt;br /&gt;
&lt;br /&gt;
Организаторы внедрили и другие нововведения. &lt;br /&gt;
Например, была целая свободная комната (мини-зал) со стульями для кулуарных обсуждений после докладов. Правда, участники, в основном, так и продолжали по старой привычке толочься в коридорах; благо, они в &amp;quot;Октябре&amp;quot; просторные.&lt;br /&gt;
Представители различных компаний, предлагающие услуги IT-сферы, расположились как-то более упорядоченно (среди них, кстати, хотелось бы отметить хостинг-провайдера &lt;a href=&quot;http://firstdecic.ru&quot;&gt;1stDEDIC&lt;/a&gt;, который предлагает выделенные сервера (не виртуальные, а настоящие, физические), начиная всего-то с 1800 руб.). Ну и неизменное массажное кресло в коридоре, которое так не хочется покидать. &lt;br /&gt;
&lt;br /&gt;
На два полных дня было запланировано более 60 докладов, проходивших в три потока.&lt;br /&gt;
&lt;br /&gt;
Открывал конференцию интригующий доклад о корейской open-source базе данных - CUBRID. &lt;br /&gt;
В &lt;a href=&quot;http://www.nhncorp.com&quot;&gt;NHN&lt;/a&gt;, флагмане корейской IT-индустрии (компания занимается, в основном, играми; имеет в общей сложности несколько десятков тысяч серверов), однажды решили, что имеющиеся корпоративные СУБД, такие как MS SQL или Oracle, не удовлетворяют всем их нуждам и в то же время дорого стоят. Поэтому в 2006 году была начата разработка собственного NoSQL-хранилища, предназначенного для хранения миллионов строк и терабайтов данных.&lt;br /&gt;
Команде разработчиков, распределенной между Кореей, Китаем и Румынией, удалось реализовать задуманное, и теперь CUBRID активно внедряется в NHN, заменяя платные продукты и сохраняя для родной компании миллионы долларов ежегодно.&lt;br /&gt;
СУБД снабжена транзакциями, высокоустойчивыми механизмами репликации, собственной файловой системой и многим другим.&lt;br /&gt;
&lt;br /&gt;
Если вы планируете разработать какой-то программный продукт не для сообщества, а с расчетом на продажу прав на него, без осведомленности об инструментах защиты своих прав придется туго. Михаил Радченко из Softpatent провел ликбез по патентованию интернет-разработок.&lt;br /&gt;
В Росии многие недооценивают обладание  патентом. А опыт показывает, что патентование повышает цену программного продукта примерно на два порядка.&lt;br /&gt;
Другая распространенная ошибка - патентование уже после начала работы, когда уже потрачены силы и средства, однако выясняется, что такое технологическое решение уже запатентовано кем-то другим. Мировые лидеры, такие как Microsoft, Google, Apple или Facebook заблаговременно проводят исследование патентного поля и выделяют на подготовку документации для патентов немало ресурсов (численность соответствующих отделов составляет десятки человек), продукт выпускается только после подачи заявки на патент, которых вышеупомянутые компании имеют сотни и тысячи. &lt;br /&gt;
Также важно помнить, что при расчете на патентование нельзя разглашать никакую информацию о продукте третьим лицам (в частности, выкладывать исходные коды в открытый доступ), в противном случае в регистрации заявки на патент будет отказано.&lt;br /&gt;
&lt;br /&gt;
Секция client-side как всегда находилась на острие технологий, представив очень интересные и технологически глубокие доклады.&lt;br /&gt;
&lt;br /&gt;
Владимир Журавлёв из Evil Martians много рассказывал про оптимизацию работы с jQuery и дал несколько полезных советов:&lt;br /&gt;
- сокращайте каскад в селекторе (длинные селекторы только медленней)&lt;br /&gt;
- группируйте частые события (типа mousemove) с помощью  &lt;a href=&quot;http://benalman.com/projects/jquery-throttle-debounce-plugin/&quot;&gt;debounce и throttle&lt;/a&gt;&lt;br /&gt;
- вставляйте элементы в DOM пакетно, а не по одному (при каждом изменении DOM-дерева происходит перерисовка страницы)&lt;br /&gt;
- кэшируйте выборки, чтобы не делать их заново лишний раз &lt;br /&gt;
- заменяйте прямую установку css-свойств на присвоение классов&lt;br /&gt;
- используйте цепочки методов&lt;br /&gt;
- много each? посмотрите в сторону &lt;a href=&quot;http://jsperf.com/jquery-each-vs-quickeach&quot;&gt;quickEach&lt;/a&gt; - будет быстрее где-то на порядок.&lt;br /&gt;
Кстати. Во время ответов на вопросы выяснилось, что есть еще места, где активно используют IE6, одно из них - Украинская Рада.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://lomov.ru/&quot;&gt;Артемий Ломов&lt;/a&gt; держал речь о производительности  CSS-селекторов.  &lt;br /&gt;
Неочевидным, но весьма важным является то обстоятельство, что селекторы применяются справа налево (с конца, то есть). Например, чтобы применить стиль для селектора &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re1&quot;&gt;.menu&lt;/span&gt; a&lt;/span&gt;, браузер сначала найдет все теги &amp;lt;a&amp;gt;, потом для каждого из них поднимется по DOM-дереву, выясняя, можно ли найти родителя с классом &amp;quot;menu&amp;quot;, и только после этого применит стиль. Именно из-за такого, восходящего, порядка проверки, например, селектор &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re1&quot;&gt;.link&lt;/span&gt;&lt;/span&gt; будет работать быстрее, чем &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re1&quot;&gt;.menu&lt;/span&gt; &lt;span class=&quot;re1&quot;&gt;.link&lt;/span&gt;&lt;/span&gt;. Поэтому с точки зрения производительности  выгодней использовать направленные имена классов, без каскада. &lt;br /&gt;
Впрочем, здесь нужно знать меру и все же отдавать должное семантике документа, не впадая в крайности типа &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;re1&quot;&gt;.ordered-list&lt;/span&gt;&lt;/span&gt; вместо &lt;span class=&quot;code css&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;ol li&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Антон Немцев представил очень яркий и интересный доклад про 3D-эффекты с помощью CSS.&lt;br /&gt;
Да, да. 3D. Конечно, как обычно, в IE меньше 10 не работает, так что приходится заботиться о деградации. Но всё же совершенно реально и уже применяется на работающих проектах.&lt;br /&gt;
3D в CSS создается с помощью свойства &lt;a href=&quot;http://www.w3.org/TR/css3-3d-transforms/&quot;&gt;transform&lt;/a&gt;, дополненного инструкциями по анимации - свойством transition.&lt;br /&gt;
transform предписывает применить к элементу некое пространственное преобразование - сдвиг вдоль координатной оси, поворот вокруг координатной оси и др., transition указывает, за какое время должно происходить преобразование (при отсутствии transition преобразование применяется сразу), а также некоторые другие его параметры.&lt;br /&gt;
С помощью этих средств можно создавать совершенно поразительные по виду страницы, где блоки поворачиваются, отъезжают вдаль от зрителя и вообще ведут себя гораздо более неожиданно, чем того ждешь от простого HTML в браузере. Примером может служить  &lt;a href=&quot;http://websaints.net/rit/rit.zip&quot;&gt;презентация Антона&lt;/a&gt;, сверстанная с использованием только HTML и CSS, а также сайты &lt;a href=&quot;http://christianheilmann.com&quot;&gt;christianheilmann.com&lt;/a&gt;, &lt;a href=&quot;http://2012.beercamp.com&quot;&gt;2012.beercamp.com&lt;/a&gt;, &lt;a href=&quot;http://wannafun.ru&quot;&gt;wannafun.ru&lt;/a&gt;, &lt;a href=&quot;http://acko.net&quot;&gt;acko.net&lt;/a&gt;, &lt;a href=&quot;http://stuffandnonsense.co.uk/content/demo/cannybill/21-10-2009/pricing.html&quot;&gt;CannyBill&lt;/a&gt; и др.&lt;br /&gt;
&lt;br /&gt;
Тему 3D средствами CSS/Javascript продолжил Андрей Ситник из Evil Martians, продемонстрировав, что 3D может использоваться  не только для красоты, но и для повышения комфорта пользователя, делая происходящее на экране более похожим на реальный мир засчет имитации физики.&lt;br /&gt;
Кстати, Андрей упомянутл о библиотеке &lt;a href=&quot;http://modernizr.com/&quot;&gt;Modernizr&lt;/a&gt;, которая позволяет быстро определить, поддерживает ли текущий браузер и ОС 3D-инструменты. А в jQuery для анимации свойства translate, поскольку оно не цифровое, требуется расширение &lt;a href=&quot;https://github.com/sproutcore/TransformJS&quot;&gt;TransformJS&lt;/a&gt;. &lt;br /&gt;
А еще в &lt;a href=&quot;http://evl.ms/rit3d&quot;&gt;презентации Андрея&lt;/a&gt; есть простые примеры CSS-кода, реализующего анимацию. &lt;br /&gt;
CSS - не единственное средство создания трехмерной графики в браузерах. Активно развивается стандарт &lt;a href=&quot;http://ru.wikipedia.org/wiki/WebGL&quot;&gt;WebGL&lt;/a&gt;, реализующий передачу низкоуровневых OpenGL-комманд видеокарте напрямую из JavaScript на основе HTML-тэга &amp;lt;canvas&amp;gt;. Вот несколько примеров его работы: &lt;a href=&quot;https://www.google.com/search?q=tan%28abs%28x/2%29%2Babs%28y/2%29%29&quot;&gt;трехмерный просмотр графика функции от Google&lt;/a&gt;, &lt;a href=&quot;http://madebyevan.com/webgl-water/&quot;&gt;вода&lt;/a&gt;, &lt;a href=&quot;https://chrome.google.com/webstore/detail/hdahlabpinmfcemhcbcfoijcpoalfgdn&quot;&gt;браузерная 3D-игра с роботами&lt;/a&gt;, &lt;a href=&quot;http://www.google.ru/nexus/&quot;&gt;обзор телефона&lt;/a&gt;.&lt;br /&gt;
Также разрабатывается стандарт &lt;a href=&quot;http://www.khronos.org/webcl/wiki/Main_Page&quot;&gt;WebCL&lt;/a&gt;, целью которого является предоставление возможности передачи команд не центральному процессору, а процессору видеокарты, в графических расчетах более производительному. &lt;br /&gt;
Следует отметить, что отрисовка трехмерной графики - процесс ресурсоемкий. На не очень новых ОС (например, Windows до семерки) для обработки 3D не включается аппаратное ускорение, поэтому работать будет медленно. &lt;br /&gt;
&lt;br /&gt;
Александр Сидоров и Петр Волков из Яндекса делились богатым опытом работы с зараженными сайтами, рассказывали о путях, которые могут привести к заражению и о том, как это предотвратить.&lt;br /&gt;
Возможностей получить на своем сайте посторонний код существует немало: от украденных FTP-паролей до уязвимостей в CMS и в программном коде самого сайта. Но, пожалуй, два самых неожиданных места - это недобросовестные партнерские программы (на сайт устанавливается код, например, рекламной сети, который занимается рассылкой приглашений на страницу с эксплойтом; всегда проверяйте, с кем имеете дело!) и зараженные сервера на хостинге. &lt;br /&gt;
Вирусы бывают очень хитры (например, не показываются залогиненным администраторам; показываются неравномерно, не давая воспроизводимости; показываются определенному диапазону ip-адресов и др.).&lt;br /&gt;
Наиболее распространенные площадки для работы вирусов - китайские, индийские и польские сайты (.cn, .in, .pl).&lt;br /&gt;
&lt;br /&gt;
Завершали конференцию блиц-доклады (легкие пятиминутные выступления без дискуссии).&lt;br /&gt;
&lt;br /&gt;
РИТ++ по-прежнему остается одним из главных отраслевых мероприятий, позволяя быть в курсе событий, творящихся в сфере интернет-технологий. </description>
</item>
<item>
  <title>Вышла стабильная версия MariaDB 5.3.5</title>
  <link>http://webew.ru/posts/4183.webew</link>
  <guid>http://webew.ru/posts/4183.webew</guid>
  <pubDate>Thu, 01 Mar 2012 02:09:52 +0400</pubDate>
  <description>Вышла MariaDB 5.3.5 - первая стабильная версия в ветке 5.3.&lt;br /&gt;
&lt;br /&gt;
Среди изменений:&lt;br /&gt;
* Оптимизация подзапросов, которая наконец делает подзапросы пригодными к использованию. Оптимизатор сам при необходимости переделывает подзапросы в JOIN.&lt;br /&gt;
* Изменения оптимизатора:&lt;br /&gt;
    1. &lt;a href=&quot;http://kb.askmonty.org/en/block-based-join-algorithms&quot;&gt;Hash join&lt;/a&gt;,&lt;br /&gt;
    2. &lt;a href=&quot;http://askmonty.org/wiki/Manual:Batched_Key_Access&quot;&gt;Batched Key Access&lt;/a&gt;&lt;br /&gt;
    3. &lt;a href=&quot;http://kb.askmonty.org/en/multi-range-read-optimization&quot;&gt;оптимизация использования индекса для range-запросов,&lt;/a&gt;&lt;br /&gt;
    4. &lt;a href=&quot;http://kb.askmonty.org/en/index-condition-pushdown&quot;&gt;проверка части условий where при обращении к индексу,&lt;/a&gt;&lt;br /&gt;
* Включен плагин HandlerSocket, реализующий NoSQL доступ к базе данных.&lt;br /&gt;
* &lt;a href=&quot;http://kb.askmonty.org/en/group-commit-for-the-binary-log&quot;&gt;Групповой коммит в XtraDB&amp;lt;/a&amp;gt; при включенном бинарном журнале.&lt;/a&gt;&lt;br /&gt;
* Улучшения производительности в Windows.&lt;br /&gt;
&lt;br /&gt;
MariaDB доступна на сайте &lt;a href=&quot;http://downloads.askmonty.org/mariadb/5.3.5/&quot;&gt;Ask Monty&lt;/a&gt;.</description>
</item>
<item>
  <title>РИТ++, Москва, 2-3 апреля 2012</title>
  <link>http://webew.ru/posts/4180.webew</link>
  <guid>http://webew.ru/posts/4180.webew</guid>
  <pubDate>Wed, 29 Feb 2012 17:35:27 +0400</pubDate>
  <description>2 и 3 апреля в Москве пройдет конференция &lt;a href=&quot;http://ritconf.ru/&quot;&gt;«Российские Интернет технологии» (РИТ++ 2012)&lt;/a&gt; — профессиональная конференция &amp;quot;от разработчиков для разработчиков&amp;quot;. Ежегодно на РИТ++ встречаются лучшие эксперты крупнейших российских и международных компаний, разработчики браузеров и баз данных, языков программирования и веб-серверов, тимлиды и ведущие разработчики! В общем, все те, кто своими руками ежедневно ДЕЛАЕТ интернет.&lt;br /&gt;
&lt;br /&gt;
Конференция будет сфокусирована на новом - новых технологиях, новых методах масштабирования, новых подходах к верстке мобильных сайтов, на всем перспективном, неожиданном и необычном. В этом году мероприятие охватит следующие направления:&lt;br /&gt;
&lt;br /&gt;
 + Системное администрирование: операционные системы, сети, дата-центры, SaaS, безопасность, облака;&lt;br /&gt;
 + Базы данных: производительность и оптимизация, NoSQL, отказоусточивость и масштабируемость;&lt;br /&gt;
 + Технологии будущего (мы еще не знаем, что будет представлено в этом году);&lt;br /&gt;
 + Управление проектами: методологии, инструменты, командообразование, мотивация;&lt;br /&gt;
 + Качество: управление качеством, функциональное и нагрузочное тестирование;&lt;br /&gt;
 + Клиентское программирование: в этом году мы планируем встречу разработчиков веб-браузеров! А также JavaSocript, HTML5, RichMedia и мобильные приложения;&lt;br /&gt;
 + Серверное программирование: Perl, C/C++, PHP, Ruby, Python, Java.&lt;br /&gt;
&lt;br /&gt;
На РИТ++ 2012 выступит Ян Плоскер, разработчик масштабируемой, отказоустойчивой распределенной базы данных Riak. Это не просто &amp;quot;еще одна NoSQL&amp;quot;, а действительно новое решение.  Только взгляните:&lt;br /&gt;
 + Теперь вам не нужно беспокоиться о единой точке отказа, т.к. в Riak нет master-node.&lt;br /&gt;
 + Забудьте про надежность оборудования! Вы можете лишиться нескольких нод кластера, но по-прежнему сможете получить свои данные.&lt;br /&gt;
 + Идеально подходит для всех web-приложений: как интенсивно пишущим, так и активно считывающим данные из базы данных.&lt;br /&gt;
 + Забудьте про планирование свободного места. Просто закажите еще серверов, подключите их к кластеру и тут же получите дополнительно пространство для новых данных.&lt;br /&gt;
&lt;br /&gt;
Зарегистрироваться на конференцию можно &lt;a href=&quot;http://ritconf.ru&quot;&gt;на официальном сайте конференции&lt;/a&gt;. &lt;br /&gt;
Стоимость участия возрастает с приближением конференции.</description>
</item>
<item>
  <title>Оптимизация запросов MySQL с использованием пользовательских переменных </title>
  <link>http://webew.ru/articles/3923.webew</link>
  <guid>http://webew.ru/articles/3923.webew</guid>
  <pubDate>Thu, 24 Nov 2011 03:13:45 +0400</pubDate>
  <description>&lt;div class=&quot;indented&quot;&gt;
&lt;p&gt;&lt;b&gt;Введение.&lt;/b&gt; В современном мире существует большое количество задач, в рамках которых приходится обрабатывать большие массивы однотипных данных. Яркими примерами являются системы для анализа биржевых котировок, погодных условий, статистики сетевого трафика. Многие из этих систем используют различные реляционные  базы данных, в таблицах которых содержатся такие объемы данных, что правильное составление и оптимизация запросов к этим таблицам становится просто необходимым для нормального функционирования системы. В этой статье описаны методы решения ( и сравнительные временные характеристики используемых методов ) нескольких задач по получению данных из таблиц СУБД &lt;i&gt;MySQL&lt;/i&gt;, содержащих статистику о проходящем через маршрутизаторы одного из крупных российских сетевых провайдеров сетевом трафике. Интенсивность потока данных, поступающего с главного маршрутизатора такова, что ежесуточно в таблицы базы данных используемой системы мониторинга сетевого трафика поступает  в среднем от 400 миллионов до миллиарда записей, содержащих информацию о транзакциях &lt;i&gt;TCP/IP&lt;/i&gt; (рассматриваемый маршрутизатор экспортирует данные по протоколу &lt;i&gt;netflow&lt;/i&gt;). В качестве СУБД для системы мониторинга используется &lt;i&gt;MySQL&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Использование баз данных.&lt;/b&gt; Запросы в теории реляционных баз данных базируются на концепции операций над множествами, а в теории множеств концепция времени отсутствует. В действительности же всё иначе: СУБД реализуют абстрактные концепции на базе реального оборудования. В результате выполнение запросов требует много (иногда чрезвычайно много) времени, и не всегда есть возможность ждать длительное время, поэтому проблема поиска путей ускорения применяемых запросов стоит достаточно остро -   благо, эти пути существуют. Один из основных и наиболее часто применяемых способов – индексирование таблиц, позволяющее ускорить их просмотр. Другой способ – создание запросов, оказывающих влияние на механизм планирования, позволяющий запросам различных клиентов взаимодействовать более эффективно. Также существует возможность модифицировать настройки аппаратной части, позволяющие повысить производительность, обойдя физические ограничения, присущие тому или иному типу оборудования.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Работа с индексами&lt;/b&gt;. Таблица, в который нет индексов, представляет собой беспорядочный набор строк, и для поиска нужной записи, допустим по id, необходимо проверить все ее строки на совпадение с искомым значением, для этого нужно просканировать всю таблицу от начала до конца. Это может занять много времени и будет исключительно неэффективно, особенно если таблица содержит только несколько записей, удовлетворяющих условию поиска.
&lt;br /&gt;
В качестве примера рассмотрим таблицу, содержащую подведомственные рассматриваемому интернет-провайдеру организации. В данном контексте в таблице присутствует два поля – id организации (&lt;b&gt;org_id&lt;/b&gt;) и название организации (&lt;b&gt;org_name&lt;/b&gt;).&lt;/p&gt;
&lt;p&gt;Допустим, мы добавили индекс на  поле &lt;b&gt;org_id&lt;/b&gt; (см. Рис. 1 ). Индекс содержит запись о каждой строке из таблицы, и записи индекса отсортированы по значению &lt;b&gt;org_id&lt;/b&gt;. Теперь вместо сканирования всех записей в таблице мы можем воспользоваться индексом. Предположим, что требуется найти строку, содержащую запись об организации (&lt;i&gt;Институт автоматики и электрометрии СО РАН&lt;/i&gt;), у которой уникальный идентификатор (&lt;b&gt;org_id&lt;/b&gt;) равен 2. Сканирование по индексу возвращает одну строку. Значения в индексе отсортированы по возрастанию, поэтому достижении следующего значения (с &lt;b&gt;org_id&lt;/b&gt; равным &lt;i&gt;3&lt;/i&gt;) можно завершать сканирование: после &lt;i&gt;3&lt;/i&gt; мы уже не найдем нужных значений. В случае, если искомые значения находятся где-то посередине таблицы, с помощью специальных алгоритмов (например, методом бинарного поиска) можно перейти к нужной строке без длительного линейного сканирования таблицы.&lt;/p&gt;
&lt;div style=&quot;text-align:center&quot;&gt;&lt;img src=&quot;http://webew.ru/f/MG5uzqO1.png&quot; /&gt;&lt;br /&gt;Рис. 1. Взаимодействие с таблицей, с использованием индекса&lt;/div&gt;
&lt;p&gt;В целом, большинство запросов можно оптимизировать, если правильно создать нужные индексы в таблице и построить запрос так, чтобы они эффективно использовались. Однако существуют такие запросы, скорости выполнения которых отнюдь не помогают индексы - например, в случае, когда по индексу выбирается больше чем около 1/10 всех записей в таблице, оптимизатор предпочтет &lt;i&gt;FTS (Full Table Scan)&lt;/i&gt; вместо использования индекса, поскольку последовательное чтение с диска происходит быстрее, чем читать из разных частей диска (передвижение головки по диску — &lt;i&gt;seek&lt;/i&gt; — это “дорогая” операция). Оптимизатор можно “заставить” использовать индекс, используя опцию &lt;b&gt;FORCE INDEX&lt;/b&gt;, но это обычно не даёт выигрыша в скорости. Также таблицы могут быть такого большого размера, что создание индекса будет непрактичным с точки зрения занимаемого объема или  длительности выполнения операции. Кроме того, за удобство использования индексов приходится определенным образом “расплачиваться”, у индексов есть свои недостатки. В большинстве своем они незначительны, но о них стоит знать.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Недостатки использования индексов.&lt;/b&gt; Во-первых, индексы ускоряют поиск данных, но замедляют операции добавления, удаления и модификации данных в индексируемых столбцах, поскольку при каждом изменении данных в такой таблице приходится перестраивать индекс. Взаимосвязь тут простая: чем больше индексов имеет таблица, тем больше замедление операций над записями.&lt;/p&gt;
&lt;p&gt;Во-вторых, индексный файл занимает определенное место на диске (нередки случаи, когда индексы занимают больше места, чем сами данные). При создании большого количества индексов, размер такого индексного файла может быстро достичь максимального размера. Это может стать причиной достижения предельного размера таблицами быстрее, чем это было бы без использования индексов.
&lt;ul&gt;
&lt;li&gt;Для таблиц типа &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/myisam-storage-engine.html&quot; &gt;MyISAM&lt;/a&gt; излишнее индексирование таблиц может привести к достижению индексным файлом его максимального размера быстрее, чем файлом данных ( проблему можно решить с помощью &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.1/en/partitioning.html&quot;&gt;PARTITIONING&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Таблицы типа &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/bdb-storage-engine.html&quot;&gt;BDB&lt;/a&gt; хранят данные и индексы в одном файле. Это, безусловно, является причиной более быстрого достижения максимального размера табличным файлом.&lt;/li&gt;
&lt;li&gt;Таблицы типа &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/innodb-storage-engine.html&quot;&gt;InnoDB&lt;/a&gt; размещаются в едином табличном пространстве. При добавлении индексов дисковое пространство, отведенное под табличное пространство, будет исчерпано быстрее.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Пользовательские переменные.&lt;/b&gt; MySQL поддерживает &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/user-variables.html&quot;&gt;пользовательские переменные&lt;/a&gt; (далее в тексте &lt;b&gt;ПП&lt;/b&gt;), начиная с версии 3.23.6. Переменным можно присваивать значения, и обращаться к ним позже - это можно также использовать, когда есть потребность сохранить результаты вычислений для использования в дальнейших запросах.
Например, для того, чтобы найти изделия с минимальной ценой, можно выполнить следующие действия:&lt;br /&gt;
mysql&gt; &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; @min_price:=&lt;span class=&quot;kw1&quot;&gt;MIN&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;price&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; shop;&lt;/span&gt;&lt;br /&gt;
mysql&gt; &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; * &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; shop &lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; price=@min_price;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;Пользовательские переменные записываются как &lt;b&gt;@var_name&lt;/b&gt;,  и могут принимать значения целого (&lt;b&gt;int&lt;/b&gt;), дробного (&lt;b&gt;real&lt;/b&gt;) и строчного (&lt;b&gt;string&lt;/b&gt;) типа. Присваивание переменной значения производится через оператор SET (&lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt; @var1=&lt;span class=&quot;st0&quot;&gt;'RUS'&lt;/span&gt;&lt;/span&gt;), через оператор &lt;i&gt;SELECT&lt;/i&gt; (&lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;'RUS'&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INTO&lt;/span&gt; @var1;&lt;/span&gt;) или в ходе выполнения запроса через оператор “:=” (“=” трактуется как равенство) (&lt;b&gt;@var1:=72&lt;/b&gt;).
&lt;div style=&quot;margin-bottom:10px&quot;&gt;&lt;img src=&quot;http://webew.ru/f/oZzONcjD.png&quot; /&gt;&lt;/div&gt;
Неинициализированная переменная принимает значение &lt;b&gt;NULL&lt;/b&gt;.&lt;/p&gt;
&lt;blockquote&gt;
Необходимо инициализировать переменные до выполнения запроса, так как иначе тип переменных определится в процессе выполнения самого запроса, а определится он может некорректно, в результате будет получен неверный результат. &lt;a href=&quot;http://sqlinfo.ru/forum/viewtopic.php?id=4235&quot;&gt;Пример&lt;/a&gt;,&amp;nbsp;&lt;a href=&quot;http://bugs.mysql.com/bug.php?id=61408&quot;&gt;обсуждение&lt;/a&gt;.
&lt;/blockquote&gt;
&lt;p&gt;&lt;b&gt;Преимущества использования ПП&lt;/b&gt;. Возможность сохранять промежуточные результаты в переменных и оперировать им по ходу дальнейшего выполнения запроса позволяет значительно ускорить выполнение некоторых запросов (за счет меньшего количества сканирований таблицы), а также позволяет выполнять такие запросы, которые в стандартной реляционной модели реализуются очень сложно или вовсе не реализуются.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Недостатки использования ПП.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;Сложная переносимость на другие СУБД (механизм ПП служит определенной надстройкой над реляционной моделью баз данных в рамках СУБД MySQL). Впрочем, данный недостаток не очень критичен, поскольку на данный момент все крупные СУБД имеют свои отклонения от стандарта ANSI SQL.&lt;/li&gt;
&lt;li&gt;Поведение пользовательских переменных будет зависеть от порядка выполнения сложного запроса, который может меняться оптимизатором MySQL (если не используется оператор &lt;b&gt;STRAIGHT_JOIN&lt;/b&gt;).&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Пример №1.&lt;/b&gt; Одной из важных задач в мониторинге сетевого трафика является фиксация пиков загрузки предоставляемых каналов связи от поставщиков интернета (см. Рис. 2).&lt;/p&gt;
&lt;img src=&quot;http://webew.ru/f/Wi21nHof.png&quot; /&gt;&lt;br /&gt;
&lt;div style=&quot;text-align:center&quot;&gt;Рис. 2. График, отображающий динамику загрузки канала&lt;/div&gt;
&lt;p&gt;Система мониторинга сохраняет информацию о входящем и исходящем трафике целиком, и  в частности, по каждому из каналов в отдельных таблицах. Тип таблицы – &lt;i&gt;MyISAM&lt;/i&gt;.&lt;br /&gt;Упрощенная форма таблицы такого типа:
&lt;table style=&quot;border: 1px solid&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;&lt;b&gt;t&lt;/b&gt; (временная метка)&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;&lt;b&gt;src&lt;/b&gt; (количество отданных байт)&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;&lt;b&gt;dst&lt;/b&gt; (количество принятых байт)&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;Для поиска максимального скачка входящего (также как и исходящего, но в этом случае идёт работа с полем &lt;b&gt;src&lt;/b&gt;) трафика необходимо просканировать всю таблицу, при этом сравнивая значения поля &lt;b&gt;dst&lt;/b&gt;, соответствующие  меткам t&lt;sub&gt;prev&lt;/sub&gt; (временная метка на предыдущем шаге ) и t&lt;sub&gt;curr&lt;/sub&gt; (временная метка на текущем шаге). В этом и состоит основная сложность: в рамках реляционной модели невозможно запомнить предыдущее значение в процессе сканирования таблицы и использовать его напрямую. Его можно вычислить с помощью подзапроса
&lt;br /&gt;
&lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; dst &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; t t2 &lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; t2.t&amp;lt;t1.t &lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; t2.t &lt;span class=&quot;kw1&quot;&gt;DESC&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;;&lt;/span&gt;
&lt;br /&gt;
где &lt;b&gt;t1.t&lt;/b&gt; – текущее значение временной метки), но такая конструкция сильно усложняет запрос, в общем случае сложность запроса с &lt;a href=&quot;http://en.wikipedia.org/wiki/Big_O_notation&quot;&gt;O(n)&lt;/a&gt; увеличивается до O(n&lt;sup&gt;2&lt;/sup&gt;) (из-за того, что приходится для каждой временной метки вычислять предыдущую путём сканирования всей таблицы), что сильно сказывается на скорости выполнения запроса. В случае наличия в таблице уникального индекса на поле &lt;b&gt;t&lt;/b&gt;, вычисление будет проводиться значительно быстрее, но это тогда, когда точно известно, что в таблице нет пропущенных временных меток (а такая идеальная ситуация практически не встречается), и предыдущая временная метка вычисляется просто вычитанием нужного интервала из текущей (по уникальному индексу выборка проходит очень быстро). В общем же случае значение временной метки на предыдущем шаге приходится вычислять подзапросом, основанным не на строгом равенстве, а на нестрогом, используя сортировку, и такой запрос, естественно, работает значительно дольше. В реляционном варианте в подзапросе для более быстрой выборки данных требуется индекс на поле &lt;b&gt;t&lt;/b&gt;, а во внешнем запросе идёт работа с полем &lt;b&gt;dst&lt;/b&gt;, поэтому в данном случае в таблице создан составной индекс &lt;b&gt;t_dst&lt;/b&gt; на поля (&lt;b&gt;t&lt;/b&gt;, &lt;b&gt;dst&lt;/b&gt;).
&lt;/p&gt;
&lt;p&gt;Реляционный вариант запроса:&lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;MAX&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;t1.dst-&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; dst &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; t t2 &lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; t2.t&amp;lt;t1.t &lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; t2.t &lt;span class=&quot;kw1&quot;&gt;DESC&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; t t1;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Как видно из запроса, приходится приходить по таблице n + 1 раз. пользовательские переменные позволяют  реализовать такой запрос за один проход по таблице. для того чтобы  запрос, который  осуществляет один проход по таблице сработал корректно, необходимо, чтобы данные выбирались в порядке возрастания временной метки.
этого можно достичь следующими путями.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Отсортировать данные в таблице (если это требуется) запросом &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;ALTER TABLE&lt;/span&gt; `t` &lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; `t`&lt;/span&gt; (для таблиц типа &lt;i&gt;MyISAM&lt;/i&gt; – рабочее решение) до выполнения запроса. В случае, если данные были вставлены последовательно, но из таблицы было удалено несколько записей, нужно дефрагментировать таблицу запросом &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;OPTIMIZE TABLE&lt;/span&gt; `t`&lt;/span&gt;. Поскольку данные отсортированы заранее, то в запросе применяется инструкция &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;IGNORE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INDEX&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;t_dst&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;, чтобы данные выбирались не по индексу, а последовательно.&lt;/li&gt;
&lt;li&gt;Наличие составного индекса на выбираемые (используемые в &lt;b&gt;WHERE/ORDER BY/GROUP BY&lt;/b&gt;) поля позволяет выбирать по нему (по индексу) данные – то есть в порядке возрастания выбираемого поля. В данном случае наличие составного индекса &lt;b&gt;t_dst&lt;/b&gt; на поля (&lt;b&gt;t&lt;/b&gt;,&lt;b&gt;dst&lt;/b&gt;) обеспечивает выборку данных в порядке возрастания метки &lt;b&gt;t&lt;/b&gt;. Для того чтобы оптимизатор обязательно использовал индекс при выборке, нужно применить инструкцию &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;FORCE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INDEX&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;t_dst&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Выбирать данные не из таблицы t, а из созданной из нее динамической  выборки, отсортированной по полю t по возрастанию (&lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; * &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; `t` &lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; `t`&lt;/span&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Возможность выбрать данные за один проход основана на том, что есть возможность запомнить значение столбца dst на предыдущей строке таблицы в пользовательскую переменную и сравнить его со значением dst на текущей строке таблицы.&lt;/p&gt;
Запрос, работающий с таблицей, где данные расположены в нужном порядке.
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt; @&lt;span class=&quot;kw3&quot;&gt;data&lt;/span&gt;=&lt;span class=&quot;kw3&quot;&gt;NULL&lt;/span&gt;, @next_data=&lt;span class=&quot;kw3&quot;&gt;NULL&lt;/span&gt;, @max_value=&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; @next_data:=`dst` `nextdata`,&lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;@next_data- @data&amp;gt;@max_value, @max_value:=@next_data-@&lt;span class=&quot;kw3&quot;&gt;data&lt;/span&gt;, @max_value&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;, &amp;nbsp;@&lt;span class=&quot;kw3&quot;&gt;data&lt;/span&gt;:=dst &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; `t` &lt;span class=&quot;kw1&quot;&gt;IGNORE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INDEX&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;t_dst&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; @max_value;&lt;/div&gt;
&lt;br /&gt;
Запрос, выбирающий данные в нужном порядке по индексу:
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt; @&lt;span class=&quot;kw3&quot;&gt;data&lt;/span&gt;=&lt;span class=&quot;kw3&quot;&gt;NULL&lt;/span&gt;, @next_data=&lt;span class=&quot;kw3&quot;&gt;NULL&lt;/span&gt;, @max_value=&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; @next_data:=`dst` `nextdata`,&lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;@next_data- @data&amp;gt;@max_value, @max_value:=@next_data-@&lt;span class=&quot;kw3&quot;&gt;data&lt;/span&gt;, @max_value&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;, &amp;nbsp;@&lt;span class=&quot;kw3&quot;&gt;data&lt;/span&gt;:=dst &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; `t` &lt;span class=&quot;kw1&quot;&gt;FORCE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INDEX&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;t_dst&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; @max_value;&lt;/div&gt;
&lt;br /&gt;
Запрос, сортирующий данные в процессе выборки:
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt; @&lt;span class=&quot;kw3&quot;&gt;data&lt;/span&gt;=&lt;span class=&quot;kw3&quot;&gt;NULL&lt;/span&gt;, @next_data=&lt;span class=&quot;kw3&quot;&gt;NULL&lt;/span&gt;, @max_value=&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; @next_data:=`dst` `nextdata`, &lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;@next_data - @&lt;span class=&quot;kw3&quot;&gt;data&lt;/span&gt; &amp;gt; @max_value, @max_value:=@next_data-@&lt;span class=&quot;kw3&quot;&gt;data&lt;/span&gt;, &amp;nbsp;@max_value&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;, &amp;nbsp;@&lt;span class=&quot;kw3&quot;&gt;data&lt;/span&gt;:=dst &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; * &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; `t` &lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; t&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; t1;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; @max_value;&lt;/div&gt;
&lt;br /&gt;
&lt;p&gt;В таблице 1 приведены длительности выполнения запросов (при разном количестве строк в таблице). Количество строк в таблице определяется длительностью интервала. В данном случае рассматриваются интервалы длительностью в одну минуту.&lt;/p&gt;
&lt;div style=&quot;text-align:center&quot;&gt;
&lt;table style=&quot;border: 1px solid&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Период&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Количество строк&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Реляционный вариант запроса&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Запрос с ПП (последовательная выборка)&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Запрос с ПП (сортировка в процессе выполнения)&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Запрос с ПП (сортировка осуществляется за счет выборки по индексу)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1 день&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1,440&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;2,67 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.00 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.00 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.00 сек&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1 неделя&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;10,080&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;2 мин 11 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.00 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.01 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.02 сек&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1 месяц&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;43,200&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;40 мин 1 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.02 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.04 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.07 сек&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1 год&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;525,600&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Более&amp;nbsp;трёх&amp;nbsp;суток&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.54 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.68 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.94 сек&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
Таблица&amp;nbsp;1.&amp;nbsp;Измерения&amp;nbsp;длительностей&amp;nbsp;выполнения&amp;nbsp;запросов&amp;nbsp;из&amp;nbsp;примера&amp;nbsp;№1.
&lt;/div&gt;
&lt;p&gt;Результаты измерений длительностей выполнения запросов подтверждают то, что реляционный вариант запроса в данном случае  абсолютно неприменим, а все варианты запросов с пользовательскими переменными выполняются быстрее чем за секунду, что в большинстве случаев приемлемо.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Пример №2.&lt;/b&gt; Для анализа загрузки канала регулярно приходится оценивать загрузку за определенные временные промежутки (по несколько секунд, несколько минут). В данном случае выбран интервал с длительностью 5 секунд. Структура таблицы, из которой выбираются данные - такая же, как в примере №1, временная метка &lt;b&gt;t&lt;/b&gt; должна иметь тип &lt;b&gt;TIMESTAMP&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;Реляционным запросом такая выборка реализуется через группировку с последующей сортировкой результатов: &lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; `t`-&lt;span class=&quot;kw1&quot;&gt;INTERVAL&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;UNIX_TIMESTAMP&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;`t`&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;%&lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;SECOND&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt; s5,SUM&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;`dst`&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt; `d` &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; `t` &lt;span class=&quot;kw1&quot;&gt;GROUP&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; s5 &lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; `t`&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Помимо полного прохода по таблице в данном запросе еще реализуется группировка и сортировка результатa.&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Тот же запрос можно реализовать через пользовательские переменные с меньшей нагрузкой  за счет отсутствия явной группировки, и, следовательно, сортировки (при условии, что в таблице нет пропущенных временных меток).&lt;/p&gt;
Запрос, работающий с таблицей, где данные расположены в нужном порядке:&lt;br /&gt;
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt; &amp;nbsp;@c:=&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &amp;nbsp;`t`, `dst` &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &amp;nbsp;`t`, &lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;UNIX_TIMESTAMP&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;`t`&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; % &lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;, @c := @c+`dst`, @c := `dst`&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt; `dst`, &lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;UNIX_TIMESTAMP&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;`t`&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; + &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; % &lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt; &amp;nbsp;`mark` &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; `t` &lt;span class=&quot;kw1&quot;&gt;IGNORE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INDEX&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;`t_dst`&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; t1 &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; &amp;nbsp;mark = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;
&lt;br /&gt;
Запрос, выбирающий данные в нужном порядке по индексу:&lt;br /&gt;
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt; &amp;nbsp;@c:=&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &amp;nbsp;`t`, `dst` &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &amp;nbsp;`t`, &lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;UNIX_TIMESTAMP&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;`t`&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; % &lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;, @c := @c+`dst`, @c := `dst`&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt; `dst`, &lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;UNIX_TIMESTAMP&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;`t`&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; + &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; % &lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt; &amp;nbsp;`mark` &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; `t` &lt;span class=&quot;kw1&quot;&gt;FORCE&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;INDEX&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;`t_dst`&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; t1 &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; &amp;nbsp;mark = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;
&lt;br /&gt;
Запрос, сортирующий данные в процессе выборки:
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SET&lt;/span&gt; &amp;nbsp;@c:=&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &amp;nbsp;`t`, `dst` &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &amp;nbsp;`t`, &lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;UNIX_TIMESTAMP&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;`t`&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; % &lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;, @c := @c+`dst`, @c := `dst`&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt; `dst`, &lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;UNIX_TIMESTAMP&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;`t`&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; + &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; % &lt;span class=&quot;nu0&quot;&gt;5&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt; &amp;nbsp;`mark` &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; * &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; `t` &lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; `t`&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; t1&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; t2 &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; &amp;nbsp;mark = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;;&lt;/div&gt;
&lt;p&gt;В рамках выполнения подзапроса сперва идёт суммирование в переменную &lt;b&gt;@c&lt;/b&gt;, и в случае, если временная метка соответствует пятисекундному интервалу, то обнуляется счетчик и метке &lt;b&gt;mark&lt;/b&gt; присваивается значение 1. Далее внешний запрос выбирает те строки, у которых &lt;b&gt;mark&lt;/b&gt; равен 1, то есть искомые.&lt;/p&gt;
&lt;p&gt;В таблице 2 приведены длительности выполнения запросов (при разном количестве строк в таблице).&lt;/p&gt;
&lt;div style=&quot;text-align:center&quot;&gt;
&lt;table style=&quot;border: 1px solid&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Период&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Количество строк&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Реляционный вариант запроса&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Запрос с ПП (последовательная выборка)&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Запрос с ПП (сортировка в процессе выполнения)&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Запрос с ПП (сортировка осуществляется за счет выборки по индексу)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1 день&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;86,400&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.11 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.05 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.1 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.08 сек&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1 неделя&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;604,800&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.86 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.33 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.73 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.6 сек&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1 месяц&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;2,592,000&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;33.72 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1.65 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;3.62 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;2.83 сек&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1 сезон&lt;br /&gt;(3&amp;nbsp;месяца)&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;7,776,000&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;2 мин 45 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;4,87 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;10.46 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;8.36 сек&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
Таблица 2. Измерения длительностей выполнения запросов из примера №2
&lt;/div&gt;
&lt;p&gt;Как и в первом примере, приведенные варианты запросов с использованием пользовательских переменных MySQL работают в несколько раз быстрее.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Пример №3&lt;/b&gt;. С точки зрения работы сети подведомственные организации описываются определенными техническими характеристиками, в частности, выделенными для организации диапазонами IP-адресов. Иногда возникает потребность вычленить самые крупные непрерывные блоки IP-адресов, выделенные для организации.&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Таблица организаций и их сетевых диапазонов (nets) представлена следующим образом:&lt;/p&gt;
&lt;table style=&quot;border: 1px solid&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid;padding:5px&quot;&gt;&lt;b&gt;org_id&lt;/b&gt;&lt;br /&gt;(id&amp;nbsp;организации)&lt;/td&gt;
&lt;td style=&quot;border: 1px solid;padding:5px&quot;&gt;&lt;b&gt;org_name&lt;/b&gt;&lt;br /&gt;(название&amp;nbsp;организации)&lt;/td&gt;
&lt;td style=&quot;border: 1px solid;padding:5px&quot;&gt;&lt;b&gt;net&lt;/b&gt;&lt;br /&gt;(адрес&amp;nbsp;сети,&amp;nbsp;4&amp;nbsp;байта)&lt;/td&gt;
&lt;td style=&quot;border: 1px solid;padding:5px&quot;&gt;&lt;b&gt;net&lt;/b&gt;&lt;br /&gt;(маска&amp;nbsp;сети,&amp;nbsp;4&amp;nbsp;байта)&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;В случае, если нужно выбрать самый крупный непрерывный сетевой диапазон у каждой организации, особых сложностей нет. Но если необходимо выбрать по два самых крупных сетевых диапазона – реляционный вариант запроса на выборку становится достаточно сложным – необходимо для каждого диапазона посчитать количество более крупных сетевых диапазонов, после отсеять те, которые меньше первых двух (подробнее см. &lt;a href=&quot;http://sqlinfo.ru/forum/viewtopic.php?id=1742&quot;&gt;здесь&lt;/a&gt;).&lt;/p&gt;
Вариант запроса в реляционной модели:
&lt;div class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; t1.org_id,&lt;br /&gt;
&amp;nbsp; &amp;nbsp; t1.org_name, &amp;nbsp;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;*&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;`nets` t2 &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;t2.org_id = t1.org_id &lt;span class=&quot;kw1&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;t2.mask&amp;lt;&amp;lt;&lt;span class=&quot;nu0&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;+t2.net&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &amp;lt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;t1.mask&amp;lt;&amp;lt;&lt;span class=&quot;nu0&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;+t1.net&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; c, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; inet_ntoa&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;t1.net&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; inet_ntoa&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;t1.mask&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; nets t1 &lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;HAVING&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; c&amp;lt;&lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt; &lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; org_id, mask;&lt;/div&gt;
&lt;p&gt;С помощью пользовательских переменных можно в рамках одного прохода подсчитывать количество выведенных сетевых диапазонов и обнулять счетчик при смене организации. В случае, если счетчик достигает нужного значения (в данном случае 2), записи не выводятся. Саму таблицу перед использованием нужно отсортировать по размерам сетевых диапазонов в рамках организации.&lt;/p&gt;
&lt;p&gt;Вариант запроса с пользовательскими переменными MySQL:&lt;br /&gt;
&lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;set&lt;/span&gt; @i=&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;, @p=&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; &lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; t.org_id, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; t.org_name, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; inet_ntoa&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;t.net&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;, inet_ntoa&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;t.mask&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; * &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; `nets` &lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; `org_id`, `mask` &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;AS&lt;/span&gt; t &lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;WHERE&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;@p=org_id, @i:=@i&lt;span class=&quot;nu0&quot;&gt;+1&lt;/span&gt;,&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;@i:=&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;@p:=org_id&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;and&lt;/span&gt; @i&amp;lt;&lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;Большая эффективность запроса с ПП истекает из того, что в реляционном варианте запроса присутствует подзапрос, который обрабатывает каждую запись в таблице.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Пример №4.&lt;/b&gt; В предыдущих экспериментах ни разу не рассматривался вариант модификации структуры таблицы (в реальной жизни далеко не всегда ее можно или удобно менять). Однако при работе с темпоральными таблицами просто напрашивается решение сделать еще одну колонку, которая будет содержать предыдущее значение &lt;b&gt;prev&lt;/b&gt; измеряемого параметра. Для наиболее высокой скорости поиска максимального перепада значении можно добавить поле, которая будет содержать разницу &lt;b&gt;diff&lt;/b&gt; между текущим значением измерения &lt;b&gt;d&lt;/b&gt; и предыдущим.&lt;/p&gt;
&lt;p&gt;Рассмотрим вариант изменения структуры таблицы – добавление колонки &lt;b&gt;prev&lt;/b&gt;. Исходная таблица  с данными такова:
&lt;table style=&quot;border: 1px solid&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;border: 1px solid;padding:5px&quot;&gt;&lt;b&gt;t&lt;/b&gt;&amp;nbsp;(временная метка)&lt;/td&gt;
&lt;td style=&quot;border: 1px solid;padding:5px&quot;&gt;&lt;b&gt;d&lt;/b&gt;&amp;nbsp;(данные измерения)&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;Таблица не содержит индексов и первичного ключа – при наличии индекса на поле &lt;b&gt;t&lt;/b&gt; или составного индекса на поля (&lt;b&gt;t,d&lt;/b&gt;) реляционный вариант запроса работает &lt;a href=&quot;http://sqlinfo.ru/forum/viewtopic.php?id=4973&quot;&gt;значительно медленнее&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Вариант модификации в рамках реляционной модели БД:&lt;br /&gt;
&lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;CREATE TABLE&lt;/span&gt; &amp;nbsp;`t_modifyed` &lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; t, &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; `d` &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; `t` `&lt;span class=&quot;kw1&quot;&gt;in&lt;/span&gt;` &amp;nbsp;&lt;span class=&quot;kw1&quot;&gt;where&lt;/span&gt; `&lt;span class=&quot;kw1&quot;&gt;in&lt;/span&gt;`.t &amp;lt; `out`.`t` &lt;span class=&quot;kw1&quot;&gt;order&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;by&lt;/span&gt; t &lt;span class=&quot;kw1&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;limit&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt; &amp;nbsp;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; prev, d &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; `t` `out` &lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; `t`;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Вариант модификации с использованием пользовательских переменных:
&lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;set&lt;/span&gt; @v = &lt;span class=&quot;kw3&quot;&gt;NULL&lt;/span&gt;; &lt;span class=&quot;kw1&quot;&gt;CREATE TABLE&lt;/span&gt; `t_moifyed` &lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; t, @v prev, @v:=d d &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; `t` &lt;span class=&quot;kw1&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;BY&lt;/span&gt; `t`;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;В таблице 3 приведены длительности выполнения запросов (при разном количестве строк в таблице).&lt;/p&gt;
&lt;div style=&quot;text-align:center&quot;&gt;
&lt;table style=&quot;border: 1px solid&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Период&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Количество строк&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Реляционный вариант запроса&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Запрос с ПП (последовательная выборка)&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;Запрос с ПП (сортировка в процессе выполнения)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1 день&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1,440&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.35 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.00 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.00 сек&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1 неделя&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;10,800&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;12.33 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.00 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.01 сек&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1 месяц&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;43,200&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;3 мин 45 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.10 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.15 сек&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;1 год&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;525,600&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;более 5 часов&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.54 сек&lt;/td&gt;
&lt;td style=&quot;padding:5px;border: 1px solid&quot;&gt;0.96 сек&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
Таблица 3. Измерения длительностей выполнения запросов из примера №4.
&lt;/div&gt;
&lt;p&gt;&lt;b&gt;Другие способы применения.&lt;/b&gt; Многие реляционные СУБД позволяют в ходе выполнения запроса использовать номер текущей строки вывода.
&lt;ul&gt;
&lt;li&gt;Oracle (переменная: rownum)&lt;/li&gt;
&lt;li&gt;Microsoft SQL (функция ROW_NUMBER())&lt;/li&gt;
&lt;li&gt;PostgreSQL  (функция ROW_NUMBER())&lt;/li&gt;
&lt;/ul&gt;
В MySQL rownum можно корректно эмулировать только с помощью пользовательских переменных:&lt;br/&gt;
&lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;set&lt;/span&gt; @n:=&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;select&lt;/span&gt; @n:=@n&lt;span class=&quot;nu0&quot;&gt;+1&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;as&lt;/span&gt; rownum, t.* &lt;span class=&quot;kw1&quot;&gt;from&lt;/span&gt; t;&lt;/span&gt;
&lt;br /&gt;
Строго говоря, в MySQL нет небходимости использовать rownum: для ограничения количества возвращаемых запросом строк существует инструкция LIMIT, но иногда может потребоваться.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Вывод.&lt;/b&gt; Использование пользовательских переменных в определенном типе запросов позволяет добиться большей скорости при выполнении запросов, чем в их реляционных аналогах. Это может возникать в тех случаях, если:
&lt;ul&gt;
&lt;li&gt;запрос таков, что не может эффективно использовать индексы (количество выбранных значений по индексу чересчур велико и оптимизатор делает &lt;i&gt;FTS&lt;/i&gt;);&lt;/li&gt;
&lt;li&gt;в ходе выполнения запроса используются вычисленные на предыдущих шагах и занесенные в  пользовательские переменные значения.&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Аналогичная возможность в других реляционных СУБД.&lt;/b&gt;
Механизм, аналогичный механизму пользовательских переменных имеется почти во всех современных реляционных СУБД. В данном разделе приведены примеры для PostgreSQL и Microsoft SQL. В случае использования функций, приведенных ниже необходимо учитывать то, что при их создании не были предприняты никакие действия для того, чтобы строки выбирались из таблицы в нужном порядке (по возрастанию метки &lt;b&gt;t&lt;/b&gt; ).&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.postgresql.org/&quot;&gt;&lt;b&gt;PostgreSQL&lt;/b&gt;&lt;/a&gt;: СУБД PostgreSQL не поддерживает возможность использовать пользовательские переменные в процессе выполнения запроса. Но начиная с версии 9.0 в PostgreSQL есть возможность создавать анонимные блоки кода. К сожалению, они не поддерживают формальных параметров и не возвращают значений. Однако есть возможность создать функцию в схеме &lt;a href=&quot;http://www.postgresql.org/docs/8.3/interactive/sql-createfunction.html&quot;&gt;pg_temp&lt;/a&gt;, что обеспечит автоматическое удаление функции из схемы по завершении сессии. Пример функции, вычисляющей максимальный перепад:&lt;br /&gt;
&lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;DROP FUNCTION&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;EXISTS&lt;/span&gt; pg_temp.max_drop&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;CREATE FUNCTION&lt;/span&gt; pg_temp.max_drop&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;as&lt;/span&gt; $$&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;DECLARE&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; prev &lt;span class=&quot;kw2&quot;&gt;INTEGER&lt;/span&gt;; curr &lt;span class=&quot;kw2&quot;&gt;INTEGER&lt;/span&gt;; max_ &lt;span class=&quot;kw2&quot;&gt;INTEGER&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;begin&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; max_ := &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;; prev := &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; FOR curr &lt;span class=&quot;kw1&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;SELECT&lt;/span&gt; d &lt;span class=&quot;kw1&quot;&gt;FROM&lt;/span&gt; pogoda&lt;br /&gt;
&amp;nbsp; &amp;nbsp; LOOP&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;curr - prev &amp;gt; max_&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;THEN&lt;/span&gt; max_ := curr - prev; &lt;span class=&quot;kw1&quot;&gt;END&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;IF&lt;/span&gt;; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; prev := curr;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;kw1&quot;&gt;END&lt;/span&gt; LOOP;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; RETURN max_;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;end&lt;/span&gt;&lt;br /&gt;
$$ lANGUAGE plpgsql;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.microsoft.com/sqlserver/ru/ru/default.aspx&quot;&gt;&lt;b&gt;Microsoft SQL&lt;/b&gt;&lt;/a&gt;: Основное отличие запроса от запроса с использованием ПП MySQL в том, что у переменной нужно задавать тип заранее.&lt;br /&gt;
&lt;span class=&quot;code mysql&quot; style=&quot;font-family: Consolas, monospace;&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;DECLARE&lt;/span&gt; @diff &lt;span class=&quot;kw2&quot;&gt;int&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;DECLARE&lt;/span&gt; @prev &lt;span class=&quot;kw2&quot;&gt;int&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;set&lt;/span&gt; @diff = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;set&lt;/span&gt; @prev = &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;select&lt;/span&gt; @diff = &lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;when&lt;/span&gt; @diff&amp;gt; &amp;nbsp;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;d-@prev&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;then&lt;/span&gt; @diff &lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;d-@prev&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;end&lt;/span&gt;, @prev = d &lt;span class=&quot;kw1&quot;&gt;from&lt;/span&gt; npogoda;&lt;br /&gt;
&lt;span class=&quot;kw1&quot;&gt;select&lt;/span&gt; @diff;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://oracle.com&quot;&gt;&lt;b&gt;Oracle&lt;/b&gt;&lt;/a&gt;: на момент написания этой статьи в языке Oracle SQL отсутствует возможность использовать пользовательские переменные - такая возможность имеется лишь в языке PL/SQL и таких расширениях, как SQLPLUS, Oracle XE, и. т. д.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Благодарности.&lt;/b&gt; Автор выражает благодарность за неоценимую помощь в процессе написания следующим людям:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/users/33.webew&quot; class=&quot;author&quot;&gt;Григорию Рубцову [rgbeast]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/users/177.webew&quot; class=&quot;author&quot;&gt;Василию Лукьянчикову [vasya]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/users/49.webew&quot; class=&quot;author&quot;&gt;Павлу Пушкарёву [paulus]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/users/63.webew&quot; class=&quot;author&quot;&gt;Михаилу Серову [1234ru]&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;/div&gt;</description>
</item>
<item>
  <title>Highload++ 2011. Репортаж с места событий.</title>
  <link>http://webew.ru/articles/3860.webew</link>
  <guid>http://webew.ru/articles/3860.webew</guid>
  <pubDate>Tue, 18 Oct 2011 14:20:47 +0400</pubDate>
  <description>&lt;p&gt;
	3 и 4 октября 2011 года в Москве проходила  &lt;a href=&quot;http://www.highload.ru&quot;&gt;пятая ежегодная конференция разработчиков высоконагруженных систем Highload++&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
	На два дня конференции было запланировано более 40 докладов, разбитых на два потока. Среди выступавших были представители мировых лидеров (Facebook, Microsoft, Google, Badoo) и флагманов отечественного сегмента отрасли (ВКонтакте, Одноклассники, Mail.ru и др.).
&lt;/p&gt;
&lt;p&gt;
	На этот раз стены &amp;laquo;Инфопространства&amp;raquo; вместили в себя более 700 человек. Эти внушительные цифры ощущались даже физически.
	&lt;br&gt;
	Из бытовых нововведений порадовал огромный экран в холле, который позволял лицезреть докладчика, не отрываясь от приема пищи и праздношатания, а также непрерывно функционирующую фуршетную линию, которая позволяла прием пищи практически не прекращать.
&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;http://www.highload.ru/2011/guru/13550.html&quot;&gt;Ярослав Сергеев&lt;/a&gt; из Mamba рассказал об эволюции разработки веб-проекта. Особенно о той стадии, когда сил одного технического лидера, управляющего небольшой (до 10-12 человек) группой равноправных разработчиков, начинает не хватать, и необходимы качественные изменения в стркутуре девелоперского подразделения компании.
	&lt;br&gt;
	Чтобы масштабировать разработку, программистов требуется разбить на рабочие группы во главе со старшим разработчиком-тимлидом, каждая из которых занимается определенным направлением и привязывается к определенному product-менеджеру, который отвечает за выполнение поставленных перед группой задач (т.е. у каждого PM'а своя группа).
	&lt;br&gt;
	Важной составляющей успешного процесса также является выделение отдельной группы на support — именна она (а не разработчики) занимается исправлением ошибок после выпуска очередной версии на production (при спорах вмешивается технический директор). Это разгружает разработчиков, которые не отвлекаются от решения последующих задач и потому делают их в гораздо более предсказуемые сроки, что очень повышает удобство и успешность планирования.
	Костяк support-группы должны составлять люди с определенным складом характера, любящие такую работу (таких немного, и подобрать этот костяк непросто), но саппорт подходит и для обкатки новичков, ознакомления их с внутренней структурой системы.
&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;www.highload.ru/2011/guru/13520.html&quot;&gt;Андрей Сас&lt;/a&gt; из Badoo &lt;a href=&quot;http://www.highload.ru/2011/abstracts/13451.html&quot;&gt;похвастался мощностями, пригодными для успешной отправки 100 миллионов писем в день&lt;/a&gt; (97% доставка в Inbox, среднее время от события до доставки — 25 секунд).
	&lt;br&gt;
	Добиться таких выдающихся результатов удалось, спроектировав и построив мощную, но достаточно простую систему отправки писем, развернутую на двух географически распределенных кластерах из 10 машин, на разработку которой потребовалось 1.5 человеко-года.
	&lt;br&gt;
	Система работает асинхронно: есть отдельная очередь на генерацию писем и отдельная — на отправку. Состояние обеих очередей включено в мониторинг и отслеживается на предмет переполнений. Андрей утверждает, что грамотная организация мониторинга (включая сбор информации об открытии писем с помощью вставки в них изображений-маркеров с уникальным адресом) — один из ключевых факторов успеха, без которого невозможно организовать качественную работу сервиса.
	&lt;br&gt;
	Письма хранятся в виде физических файлов (управление ими осуществляется манипуляциями на уровне каталогов файловой системы). Поэтому самый главный hardware-ресурс — это диск (в текущей конфигурации используется RAID 1+0 из 4 SSD), загрузка процессора не превышает 2-3% в пике, памяти также хватает немного — 2-4 Гб.
	В качестве MTA используются Communigate Pro (быстрый) и Postfix (медленный, но гибкий, бывает нужен для определенных типов писем).
	Единственный секрет, который Андрей не стал раскрывать — как все-таки удается спастись от спам-фильтров.
&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;http://www.highload.ru/2011/guru/13518.html&quot;&gt;Максим Лапшин&lt;/a&gt; выступил с докладом &lt;a href=&quot;http://www.highload.ru/2011/abstracts/13456.html&quot;&gt; Высокая нагрузка на erlang-приложения: erlyvideo на гигабитном канале&lt;/a&gt;.
	&lt;br&gt;
	&lt;a href=&quot;http://erlyvideo.org&quot;&gt;Видеостриминговый сервер erlyvideo&lt;/a&gt; позволяет одновременно обслуживать более 2000 пользователей с одного источника. Добиться такого результата Максиму удалось, призвав на помощь язык erlang, на освоение которого до уровня, необходимого для решения задачи, он потратил всего несколько дней.
	&lt;br&gt;
	Erlang был выбран в силу своих архитектурных особенностей, в частности очень хорошей (практически линейной) автоматической масштабируемости по ядрам процессора и возможности &quot;горячей&quot; отладки (можно внедриться прямо в работающий процесс, не приводя к заметному росту нагрузки).
	&lt;br&gt;
	Отмечатся также высокое качество работы сборщика мусора: утечек не было даже при многомесячной непрерывной работе сервера.
&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;http://www.highload.ru/2011/guru/13571.html&quot;&gt;Domas Mituzas&lt;/a&gt; рассказывал, &lt;a href=&quot;http://www.highload.ru/2011/abstracts/13593.html&quot;&gt;как в Facebook готовят MySQL&lt;/a&gt;.
	&lt;br&gt;
	При сверхвысоких нагрузках MySQL может давать сбои в самых неожиданных местах. В Facebook, где может происходить до 60 миллионов MySQL-запросов в секунду, об этом знают не понаслышке.
	&lt;br&gt;
	Возникшие проблемы команда из Facebook обычно решает самостоятельно, не дожидаясь исправления ошибок или новых релизов, и &lt;a href=&quot;https://launchpad.net/mysqlatfacebook&quot;&gt;выпускает для MySQL собственные патчи&lt;/a&gt;. Среди целевых объектов патчей — оптимизация операций DROP TABLE и ALTER TABLE (online schema change), разнообразные детали функционирования InnoDB, работа с диском и многое другое.
	&lt;br&gt;
	Впрочем, Domas назвал несколько приемов, доступных и при использовании обычных версий MySQL. Напримрер, запуск нескольких MySQL-серверов на одной машине, а также плотное использование FORCE INDEX (чтобы избежать ненужного обращения к альтернативным индексам, которые все равно использоваться не будут).
	&lt;br&gt;
	Сейчас в Facebook используют MySQL версии 5.1, но переходить планируют сразу на 5.6.
	&lt;br&gt;
	Ссылка по теме: &lt;a href=&quot;http://www.facebook.com/MySQLatFacebook&quot;&gt;MySQL в Facebook&lt;/a&gt;.
&lt;/p&gt;
&lt;!--p&gt;
&lt;a href=&quot;http://www.highload.ru/2011/guru/4454.html&quot;&gt;Петр Зайцев&lt;/a&gt; представил сравнительный обзор нововведений в стабильных и готовящихся к выпуску версиях MySQL и родственных ей СУБД — MariaDB, Percoona Server и Drizzle.
&lt;/p--&gt;
&lt;p&gt;
	&lt;a href=&quot;http://www.highload.ru/2011/guru/13365.html&quot;&gt;Константин Осипов&lt;/a&gt; и &lt;a href=&quot;http://www.highload.ru/2011/guru/13534.html&quot;&gt;Александр Календарев&lt;/a&gt; (Mail.ru) представили &lt;a href=&quot;http://www.highload.ru/2011/abstracts/13603.html&quot;&gt;noSQL-хранилище Tarantool как альтернативу Redis&lt;/a&gt;.
	По производительности Tarantool находится примерно на том же уровне, что и конкурент (сотни тысяч операций чтения и записи в секунду), но имеет важные отличительные черты в архитектуре.
	&lt;br&gt;
	Tarantool является однопоточным сервером с точки зрения использования процессора. Это делает невозможным масштабирование по ядрам, однако на практике более важным оказываются такие следствия однопоточности, как отсутствие блокировок и конкуренции за системную шину, в результате чего ограничивающими факторами производительности являются пропускная способность памяти и сетевых интерфейсов, а не процессор (на рабочих системах загрузка процессора не превышает 10-20%).
	&lt;br&gt;
	Данные Tarantool хранятся в виде пространств (аналог таблиц в традиционных СУБД) с неограниченным количеством столбцов произвольных типов, в которых хранятся записи в т.н. кортежей, имеющих произвольную размерность и типы полей.
	&lt;br&gt;
	Помимо базовых команд, есть стандартный SQL-интерфейс, а также возможность писать хранимые процедуры на языке Lua, которые выполняются сервером атомарно (без переключения контекста процессора).
	&lt;br&gt;
	Tarantool используется в ряде крупных работающих систем (в т.ч. для хранения сессий Mail.ru: 40 млн. активных пользователей, 80 Гб данных, 2 мастера + 2 реплики, шардинг по user_id).
	&lt;br&gt;
	Официальная страница Tarantool:
	&lt;a href=&quot;http://tarantool.org&quot;&gt;http://tarantool.org&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;http://www.highload.ru/2011/abstracts/13502.html&quot;&gt;Pconnect: граната в руках обезьяны&lt;/a&gt; — яркое выступление &lt;a href=&quot;http://www.highload.ru/2011/guru/13501.html&quot;&gt;Сергея Аверина&lt;/a&gt; (Badoo Development) на тему того, как может навередить неумелое использование persistent-соединений.
	&lt;br&gt;
	Работа с постоянными соединениями имеет свои подводные камни, о которых в обычной ситуации даже не задумываешься. Подводят исправно служившие в обычной ситуации средства.
	&lt;br&gt;
	Например, зачастую средствами библиотеки нельзя понять, является ли переданное соединение новым или существующим, нет возможности управлять текущими открытыми соединениями, а иногда соединение вообще нельзя закрыть.
	&lt;br&gt;
	Протокол должен предусматривать закрытие соединения при ошибках синтаксиса синхронизации (в противном случае может появляться &amp;quot;полоса сбивки&amp;quot; — битые байты проигнорируются и ответ продолжит читаться, но со сдвигом на неизвестное число байт) и идентификацию запрашивающего клиента (т.к. одно и то же соединение может передаваться между разными клиентами, без таких проверок данные могут попасть не тому, кому они предназначались; например, так в &lt;a href=&quot;http://badoo.com&quot;&gt;Badoo&lt;/a&gt; однажды залогинили 10&amp;nbsp;000 пользователей не в свои аккаунты).
&lt;/p&gt;
&lt;p&gt;
	&amp;quot;Курочка по зёрнышку клюет&amp;quot; — так можно кратко охарактеризовать доклад &lt;a href=&quot;http://www.highload.ru/2011/guru/13516.html&quot;&gt;Андрея Аксёнова&lt;/a&gt; о &lt;a href=&quot;http://www.highload.ru/2011/abstracts/13489.html&quot;&gt;низкоуровневой оптимизации C/C++&lt;/a&gt;
	&lt;br&gt;
	Создатель &lt;a href=&quot;http://sphinxsearch.com&quot;&gt;сервера полнотекстового поиска sphinx&lt;/a&gt; делился маленькими секретами низкоуровневой оптимизации, которые могут дать большой результат (&amp;quot;1% я беру&amp;quot): от учета тонких нюансов в работе процессора и памяти до замены switch на if и byte на int.
	&lt;br&gt;
	Эти небольшие оптимизации, сложенные воедино, могут давать ощутимый прирост производительности и делать системы действительно быстрее некуда.
&lt;/p&gt;
&lt;p&gt;
	&lt;a href=&quot;http://www.highload.ru/2011/guru/13540.html&quot;&gt;Иван Авсеянко&lt;/a&gt; выступил с &lt;a href=&quot;http://www.highload.ru/2011/abstracts/13470.html&quot;&gt;рассказом о column-oriented СУБД&lt;/a&gt;.
	&lt;br&gt;
	Хранение и обработка статистики зачастую требует работы со столь большими объемами данных (характерный пример — журнал посещаемости сайта с милионной посещаемостью), что традиционные СУБД не справляются. Специально для таких задач и предназначено  семейство column-oriented СУБД, в которых ячейки данных при хранении группируются не по строкам, а по столбцам (где данные, вдобавок, еще и отсортированы).
	&lt;br&gt;
	Одна из ключевых особенностей таких СУБД — степень сжатия хранимых данных, которая у некоторых из них может достигать нескольких раз (данные, однако, обычно являются read-only, поэтому частые обновления нежелательны; скорость загрузки данных — важная характеристика при практической работе с СУБД)
	&lt;br&gt;
	Другая хитрость — предварительный расчет и хранение результатов групповых операций над данными (которые для этого разбиваются на блоки, для каждой из которых и вычисляются результаты), ведь чаще всего для статистики треуются именно MAX(), MIN(), SUM() и AVG(). Кроме того, граничные значения записей позволяют планировщику определить, какие из блоков данных содержат запрашиваемые значения, и распаковывать только нужные.
	&lt;br&gt;
	Из существующих реализаций были упомянуты InfoBright, InfiniDB и MonetDB, лучшей по быстродействию и функциональности оказалась InfoBright.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;http://www.highload.ru/2011/guru/13546.html&quot;&gt;Александр Христофоров&lt;/a&gt; и &lt;a href=&quot;http://www.highload.ru/2011/guru/13547.html&quot;&gt;Олег Анастасьев&lt;/a&gt; рассказали, как в социальной сети Одноклассники хранятся бинарные данные.
&lt;br&gt;
Организовать работу с более чем полутора миллиардами фотографий (каждая из которых еще и в четырех копиях разных размерах) общим объемом 200 Тб — задача не из простых. Главными целями при этом являются достижение максимально быстрого чтения и возможность расширения кластера. Поэкспериментировав с различными ФС (Reizer, HDFS, некоторые noSQL-решения) пришли к выводу, что нужно разрабатывать своё. Что и было сделано силами одного человека в течение 3 месяцев с использованием Java (выбор пал именно на Java, т.к. на ней же написаны многие другие компоненты системы).
&lt;br&gt;
Минимальная единица оборудования — один диск (а не один сервер). Каждый диск разбивается на сегменты по 256 Мб, принадлежность конкретных файлов сегментам хранится в хэш-таблице, располагающейся в памяти (плюс копия на диске). На каждый диск приходится только один активный сегмент (тот, в который идет запись).
&lt;br&gt;
Всего используется 24 физических сервера, фактор реплики - тройка. Маршрутизация (определение хранилища, на котором располагается конкретный файл) осуществляется на основе хэша id. Таблица маршрутизации построена с использованием подхода virtual buckets: пространство хранилищ делается во много раз раз большим, чем их есть на самом деле, и несколько виртуальных хранилищ могут указывать на одно реальное (это позволяет добавлять в кластер новые единицы без необохдимости перестраивать маршрутизацию, а также распределять нагрузку по хранилищам асимметрично, если это требуется).
&lt;br&gt;
Слайды презентации: &lt;a href=&quot;http://www.highload.ru/2011/abstracts/13514.html&quot;&gt;http://www.highload.ru/2011/abstracts/13514.html&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Тезисы всех прозвучавших докладов доступны для скачивания &lt;a href=&quot;http://www.highload.ru/binary/Presentations2011.rar&quot;&gt;в виде презентаций одним архивом&lt;/a&gt;.
&lt;/p&gt;
</description>
</item>
</channel>
</rss>
