<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Заметки об HTML, CSS,  AJAX, DOM, PHP, MySQL и многом другом</title>
	<atom:link href="http://www.xpro.su/feed" rel="self" type="application/rss+xml" />
	<link>http://www.xpro.su</link>
	<description>Профессиональный Блог 4X_Pro</description>
	<pubDate>Sun, 17 Apr 2011 20:55:25 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.1</generator>
	<language>en</language>
			<item>
		<title>Новый блог!</title>
		<link>http://www.xpro.su/archives/157</link>
		<comments>http://www.xpro.su/archives/157#comments</comments>
		<pubDate>Sun, 17 Apr 2011 20:55:25 +0000</pubDate>
		<dc:creator>4X_Pro</dc:creator>
		
		<category><![CDATA[Разное]]></category>

		<guid isPermaLink="false">http://www.xpro.su/?p=157</guid>
		<description><![CDATA[Данный блог закрыт. Вместо него запускаю новый по адресу ВебБлог.РФ. И он уже будет не на WordPress (тормознутость и спам в комментариях меня достали), а на b2evolution, чего и вам советую!
]]></description>
			<content:encoded><![CDATA[<p>Данный блог закрыт. Вместо него запускаю новый по адресу <a href="http://вебблог.рф">ВебБлог.РФ</a>. И он уже будет не на WordPress (тормознутость и спам в комментариях меня достали), а на b2evolution, чего и вам советую!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xpro.su/archives/157/feed</wfw:commentRss>
		</item>
		<item>
		<title>Определение типа загруженной картинки</title>
		<link>http://www.xpro.su/archives/155</link>
		<comments>http://www.xpro.su/archives/155#comments</comments>
		<pubDate>Sun, 14 Nov 2010 22:12:59 +0000</pubDate>
		<dc:creator>4X_Pro</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[gd]]></category>

		<category><![CDATA[графика]]></category>

		<guid isPermaLink="false">http://www.xpro.su/?p=155</guid>
		<description><![CDATA[При загрузке пользователем графического файла часто возникает необходимость определить, в каком формате этот файл, чтобы применить соответствующую функцию: imagecreatefrompng, imagecreatefromjpg и т.д. Чаще всего это реализуют, проверяя расширение файла, однако это ненадежный подход (пользователь может поменять расширение файла и тем самым спровоцировать ошибки). Другой вариант &#8212; считать файл в строку и сделать createimagefromstring, однако такой [...]]]></description>
			<content:encoded><![CDATA[<p>При загрузке пользователем графического файла часто возникает необходимость определить, в каком формате этот файл, чтобы применить соответствующую функцию: imagecreatefrompng, imagecreatefromjpg и т.д. Чаще всего это реализуют, проверяя расширение файла, однако это ненадежный подход (пользователь может поменять расширение файла и тем самым спровоцировать ошибки). Другой вариант &#8212; считать файл в строку и сделать createimagefromstring, однако такой подход приводит к существенному увеличению объема требуемой для обработки изображения памяти.</p>
<p>Наиболее правильным решением является использование функции getimagesize, которая принимает в качестве параметра имя файла (а не ресурс с изображением, как многие другие) и возвращает массив из 7 элементов. Во втором элементе этого массива указывается тип изображения (его следует сравнивать с константами <span><tt>IMG_GIF,</tt></span> <span><tt>IMG_JPG</tt></span>, <span><tt>IMG_PNG</tt></span>, <span><tt>IMG_WBMP</tt></span>, <span><tt>IMG_XPM).</tt></span></p>
<p>Полезной особенностью данной функции является то, что она работает даже при отсутствии расширения gd.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xpro.su/archives/155/feed</wfw:commentRss>
		</item>
		<item>
		<title>Загрузка CSS из JavaScript</title>
		<link>http://www.xpro.su/archives/153</link>
		<comments>http://www.xpro.su/archives/153#comments</comments>
		<pubDate>Sat, 14 Aug 2010 20:15:19 +0000</pubDate>
		<dc:creator>4X_Pro</dc:creator>
		
		<category><![CDATA[CSS]]></category>

		<category><![CDATA[JavaScript, AJAX]]></category>

		<guid isPermaLink="false">http://www.xpro.su/?p=153</guid>
		<description><![CDATA[Иногда бывает необходимо загрузить стилевой файл CSS из JavaScript. (Например, если head-часть HTML уже выведена, а нарушать стандарт и подключать CSS и в body нежелательно.)
Делается это следующим образом: создается элемент link и добавляется как дочерний элемент к тегу head с помощью функций работы с DOM-моделью. Код для такого действия имеет примерно такой вид:
var tag_css = [...]]]></description>
			<content:encoded><![CDATA[<p>Иногда бывает необходимо загрузить стилевой файл CSS из JavaScript. (Например, если head-часть HTML уже выведена, а нарушать стандарт и подключать CSS и в body нежелательно.)</p>
<p>Делается это следующим образом: создается элемент link и добавляется как дочерний элемент к тегу head с помощью функций работы с DOM-моделью. Код для такого действия имеет примерно такой вид:<br />
<code>var tag_css = document.createElement('link');<br />
tag_css.rel = 'stylesheet';<br />
tag_css.href = 'http://test.ru/styles.css'; // здесь указывается URL стилевого файла<br />
tag_css.type = 'text/css';<br />
var tag_head = document.getElementsByTagName('head');<br />
tag_head[0].appendChild(tag_css);<br />
</code><br />
Если используется библиотека jQuery, то можно добавить тег несколько иначе:<br />
<code><br />
$("head").append("&lt;link&gt;");<br />
css = $("head").children(":last");<br />
css.attr({<br />
rel:  "stylesheet",<br />
type: "text/css",<br />
href: "http://test.ru/styles.css" //здесь указывается URL стилевого файла<br />
});<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.xpro.su/archives/153/feed</wfw:commentRss>
		</item>
		<item>
		<title>Конструктор для размещения видеороликов и MP3 на сайте</title>
		<link>http://www.xpro.su/archives/151</link>
		<comments>http://www.xpro.su/archives/151#comments</comments>
		<pubDate>Fri, 30 Apr 2010 14:52:17 +0000</pubDate>
		<dc:creator>4X_Pro</dc:creator>
		
		<category><![CDATA[Разное]]></category>

		<category><![CDATA[mp3]]></category>

		<category><![CDATA[видео]]></category>

		<guid isPermaLink="false">http://www.xpro.su/?p=151</guid>
		<description><![CDATA[Как правило, для проигрывания видеороликов и музыкальных MP3 на сайте размещается специальный Flash-плеер. Зачастую готовые флеш-плееры не подходят к дизайну сайта, а их доработка их требует хорошего знания Flash. 
Однако есть и другое решение: сайт UPPOD.RU. Это сайт-конструктор, на котором можно за несколько минут сделать плеер для видео, MP3 или фотографий с размерами и цветовой [...]]]></description>
			<content:encoded><![CDATA[<p>Как правило, для проигрывания видеороликов и музыкальных MP3 на сайте размещается специальный Flash-плеер. Зачастую готовые флеш-плееры не подходят к дизайну сайта, а их доработка их требует хорошего знания Flash. </p>
<p>Однако есть и другое решение: сайт <a href="http://uppod.ru">UPPOD.RU</a>. Это сайт-конструктор, на котором можно за несколько минут сделать плеер для видео, MP3 или фотографий с размерами и цветовой гаммой, подходящей под дизайн сайта. Кроме того, для плеера можно настроить список воспроизводимых файлов (причем он хранится в обычном текстовом формате, так что можно генерировать его автоматически &#8220;на лету&#8221; скриптами), задать наличие тех или иных кнопок управления и некоторых других возможностей плеера.</p>
<p>Приятной особенностью является и то, что плеер не требует обязательного показа своего логотипа или ссылки.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xpro.su/archives/151/feed</wfw:commentRss>
		</item>
		<item>
		<title>Связанные блоки</title>
		<link>http://www.xpro.su/archives/149</link>
		<comments>http://www.xpro.su/archives/149#comments</comments>
		<pubDate>Sat, 26 Dec 2009 22:36:38 +0000</pubDate>
		<dc:creator>4X_Pro</dc:creator>
		
		<category><![CDATA[CSS]]></category>

		<category><![CDATA[верстка]]></category>

		<guid isPermaLink="false">http://www.xpro.su/?p=149</guid>
		<description><![CDATA[Иногда бывает нужно сделать два блока, у которых будут стыковаться между собой рамки. (Типичная ситуация &#8212; заголовок, у которого рамка имеет один цвет, а текст под ним обрамлен рамкой другого цвета, и при этом вся конструкция должна восприниматься как едиое целое). Типичный подход в такой ситуации &#8212; использование трех тегов div примерно такого вида:
&#60;div&#62;
&#60;h1 style="border: [...]]]></description>
			<content:encoded><![CDATA[<p>Иногда бывает нужно сделать два блока, у которых будут стыковаться между собой рамки. (Типичная ситуация &#8212; заголовок, у которого рамка имеет один цвет, а текст под ним обрамлен рамкой другого цвета, и при этом вся конструкция должна восприниматься как едиое целое). Типичный подход в такой ситуации &#8212; использование трех тегов div примерно такого вида:</p>
<pre>&lt;div&gt;
&lt;h1 style="border: #ccc 1px solid"&gt;Заголовок&lt;/h1&gt;
&lt;div style="border: #888 1px solid; border-top: 0"&gt;Текст&lt;/div&gt;
&lt;/div&gt;</pre>
<p>Однако имеется более элегантное решение, позволяющее уменьшить число DOM-элементов:</p>
<pre>&lt;div style="border: #888 1px solid"&gt;
&lt;h1 style="border: #ccc 1px solid; margin: -1px"&gt;Заголовок&lt;/h1&gt;
Текст
&lt;/div&gt;</pre>
<p>Кроме того, такое решение удобно и тем, что не требует дублировать общие свойства CSS (например, выравнивание) для двух различных селекторов (внутреннего div и h1 в первом примере), их можно задавать только для внешнего divа.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xpro.su/archives/149/feed</wfw:commentRss>
		</item>
		<item>
		<title>Хранение задаваемых полей и немного об индексах MySQL</title>
		<link>http://www.xpro.su/archives/147</link>
		<comments>http://www.xpro.su/archives/147#comments</comments>
		<pubDate>Thu, 24 Dec 2009 15:18:32 +0000</pubDate>
		<dc:creator>4X_Pro</dc:creator>
		
		<category><![CDATA[Разное]]></category>

		<guid isPermaLink="false">http://www.xpro.su/?p=147</guid>
		<description><![CDATA[Иногда возникает задача хранить какие-то свойства большого количества разнородных объектов, которые никогда не будут участвовать в условиях выборки или сортировке, но которые могут добавляться/исчезать по мере развития сайта. Например, к таким свойствам относятся задаваемые поля профиля пользователя на форуме, настройки сайта в целом, какие-то опции отдельных страниц этого сайта.
В такой ситуации можно использовать универсальную таблиц [...]]]></description>
			<content:encoded><![CDATA[<p>Иногда возникает задача хранить какие-то свойства большого количества разнородных объектов, которые никогда не будут участвовать в условиях выборки или сортировке, но которые могут добавляться/исчезать по мере развития сайта. Например, к таким свойствам относятся задаваемые поля профиля пользователя на форуме, настройки сайта в целом, какие-то опции отдельных страниц этого сайта.</p>
<p>В такой ситуации можно использовать универсальную таблиц для всех настроек, которая будет иметь следющую структуру:</p>
<p>type : enum(&#8217;user&#8217;,'page&#8217;,&#8217;site&#8217;) (признак, кому принадлежит данная настройка: сайту, пользователю или странице, вместо типа enum можно использовать tinyint, чтобы не изменять структуру таблицы, если появятся новые типы объектов),<br />
id : int (идентификатор пользователя или страницы)<br />
name: varchar(24) (название опции)<br />
value: varchar(255) (значение опции).</p>
<p><span id="more-147"></span>Выборка всех свойств какого-либо объекта из такой таблицы осуществляется  запросом вида SELECT name, value FROM options WHERE id=&#8221;идентификатор_объекта&#8221; AND type=&#8221;тип_объекта&#8221;. Если число свойств у каждого конкретного объекта не очень велико (не более четырех-пяти десятков), имеет смысл выбирать все свойства данного объекта, и запоминать их на стороне скрипта. Это не сильно увеличит нагрузку на БД при первом запросе, зато потом позволит избежать повторных запросов при чтении других свойств объекта.</p>
<p>Пример такой процедуры на PHP:</p>
<pre>function get_opt($name,$id=0,$type='site') {
   $result=false;
   static $cache; // статическая переменная, в которой кешируются свойства
   if (!isset($cache[$type.$id])) {
     $sql='SELECT name, value FROM options WHERE type="'.$type.'" AND id='.intval($id);
     $res=mysql_query($sql);
     while ($data=mysql_fetch_row($res)) $cache[$type.$id][$data[0]]=$data[1];
   }
   return $cache[$type.$id][$name];
}
</pre>
<p>При этом для эффективной работы такой таблицы нужно учесть одну тонкость: PRIMARY KEY должен иметь вид (id,type,name), а не (type,id,name), как может показаться на первый взгляд. Для тех типов объектов, для которых id не предусмотрен (например, настройки сайта в целом) следует писать в этот столбец какое-то фиксированное значение, например, ноль, и указывать его в явном виде в условии при выборке свойств (т.е. WHERE id=&#8221;0&#8243; AND type=&#8221;site&#8221;). В этом случае PRIMARY KEY будет задействован при любой выборке. В других же ситуациях (например, без условия id=&#8221;0&#8243; PRIMARY KEY вида (id,type,name) при выборке объектов с type=&#8221;site&#8221; задействоваться не будет вообще, а PRIMARY KEY вида (type,id,name) может быть отброшен как неэффективный в том случае, если объектов какого-то типа будет более 30%, что вполне вероятно).</p>
<p>Если требуется обновить или добавить несколько свойств какого-либо объекта в такой таблице (и не известно, были ли такие свойства заданы ранее), имеет смысл производить это следующим образом:<br />
DELETE FROM options WHERE type=&#8221;тип&#8221; AND id=&#8221;ид_объекта&#8221; AND name IN (&#8221;свойство1&#8243;,&#8221;свойство2&#8243;,&#8230;)<br />
INSERT INTO (type,id,name,value) VALUES (&#8221;тип&#8221;,&#8221;ид&#8221;,&#8221;свойство1&#8243;,&#8221;значение1&#8243;),(&#8221;тип&#8221;,&#8221;ид&#8221;,&#8221;свойство2&#8243;,&#8221;значение2&#8243;),&#8230;.<br />
Таким образом, всего двумя запросами можно обновить или добавить любое количество свойств объекта.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xpro.su/archives/147/feed</wfw:commentRss>
		</item>
		<item>
		<title>Ограничение ширины картинки</title>
		<link>http://www.xpro.su/archives/145</link>
		<comments>http://www.xpro.su/archives/145#comments</comments>
		<pubDate>Tue, 13 Oct 2009 20:36:57 +0000</pubDate>
		<dc:creator>4X_Pro</dc:creator>
		
		<category><![CDATA[Разное]]></category>

		<category><![CDATA[CSS]]></category>

		<category><![CDATA[юзабилити]]></category>

		<guid isPermaLink="false">http://www.xpro.su/?p=145</guid>
		<description><![CDATA[Если предполагается, что сайт будут заполнять контентом неподготовленные пользователи (в смысле, не знающие HTML, CSS, да и вообще плохо разбирающиеся в компьютере), то возможны ситуации, когда они загрузят слишком большую по размеру фотографию, которая приведет к тому, что сайт &#8220;разъедется&#8221;. Конечно, правильным решением является обработка картинки на стороне сервера, но не всегда есть такая возможность.
В [...]]]></description>
			<content:encoded><![CDATA[<p>Если предполагается, что сайт будут заполнять контентом неподготовленные пользователи (в смысле, не знающие HTML, CSS, да и вообще плохо разбирающиеся в компьютере), то возможны ситуации, когда они загрузят слишком большую по размеру фотографию, которая приведет к тому, что сайт &#8220;разъедется&#8221;. Конечно, правильным решением является обработка картинки на стороне сервера, но не всегда есть такая возможность.</p>
<p>В этом случае при верстке имеет смысл принудительно ограничить ширину картинки с помощью CSS:</p>
<p>.content img { max-width: 700px }</p>
<p>где .content &#8212; это класс слоя, в котором отображается основное содержимое страницы.</p>
<p>Конечно, качество картинки при этом пострадает, но все же неудобств пользователю будет меньше, чем при растянутом сайте.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xpro.su/archives/145/feed</wfw:commentRss>
		</item>
		<item>
		<title>Закругленные углы &#8212; универсальное решение</title>
		<link>http://www.xpro.su/archives/134</link>
		<comments>http://www.xpro.su/archives/134#comments</comments>
		<pubDate>Wed, 17 Jun 2009 15:47:52 +0000</pubDate>
		<dc:creator>4X_Pro</dc:creator>
		
		<category><![CDATA[CSS]]></category>

		<category><![CDATA[HTML]]></category>

		<category><![CDATA[скругленные углы]]></category>

		<guid isPermaLink="false">http://www.xpro.su/?p=134</guid>
		<description><![CDATA[Закругленные или фигурные углы блока в настоящее время &#8212; один из самых распространенных элементов дизайна. Решений существует множество и на CSS, и на JavaScript, но большая их часть либо требует большого количества лишних пустых тегов и несемантичной верстки, либо позволяет закруглять углы только блоков с фиксированной высотой или с однородным фоном самого блока и страницы [...]]]></description>
			<content:encoded><![CDATA[<p>Закругленные или фигурные углы блока в настоящее время &#8212; один из самых распространенных элементов дизайна. Решений существует множество и на CSS, и на JavaScript, но большая их часть либо требует большого количества лишних пустых тегов и несемантичной верстки, либо позволяет закруглять углы только блоков с фиксированной высотой или с однородным фоном самого блока и страницы под ним.</p>
<p>Однако есть универсальное решение этой проблемы, которое может применяться в решениях любой сложности. Выглядит оно следующим образом: над блоком с контентом, которому нужны углы, добавляем два блока, высота которых равна радиусу скругления, с горизонтальными полями (margin), также равными отступу. Фон этого блока по цвету совпадает с фоном блока контента. Внутри этого блока помещаем еще два блока, у первого из которых отрицательным является левое поле, у второго &#8212; правое (величина отступа опять же равна радиусу скругленного угла). Для этих углов задаем фоновые картинки и отменяем фоновый цвет.</p>
<p>Далее идет блок с контентом, после которого вставляется еще один блок, полностью аналогичный верхнему, но углы скруглены вниз.<span id="more-134"></span></p>
<p>В виде HTML-кода это выглядит примерно следующим образом:</p>
<pre>&lt;div class="topline"&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="content"&gt;Здесь идет контент&lt;/div&gt;
&lt;div class="bottomline"&gt;&lt;div&gt;&lt;div&gt;
Здесь тоже может быть текст, который должен показываться в самом низу блока, например, copyright-сообщение
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</pre>
<p>CSS будет иметь такой вид:</p>
<pre>.topline, .content, .bottomline {width: ...} /* Задаем единую ширину для всех блоков, желающие могут поместить их в общий контейнер и задавать ширину для него. */
.topline, .bottomline { margin: 0px 19px } /* В данном примере радиус угла скругления -- 19px */
.topline div, .bottomline div { margin-left: -19px  }
.topline div div, .bottomline div div { margin-right: -19px; height: 19px }

.topline { background: url('mback2.jpg'); background-repeat: repeat-x } /* В данном примере для вложенного блока используется градиентный фон. Файл mback2.jpg содержит самую верхнюю часть градиента */
.topline div { background-image: url('corn_tl.gif'); background-repeat: no-repeat; } /* Верхний левый уголок */
.topline div div { height: 19px; background-image: url('corn_tr.gif'); background-position: right; background-repeat: no-repeat; } /* Верхний правый уголок. Здесь же задаем высоту, равную радиусу скругления. Если радиус маленький, не забываем про font-size: 0 для MSIE */

.content { padding: ...; margin: ...; background-image: url('mback.jpg') }  /* Основная часть градиента */

.bottomline { background: #000; } /* В нижней части блока наш градиент плавно перешел в черный цвет, чтобы блок можно было растягивать по высоте настолько, насколько потребуется */
.bottomline div { background: url('corn_bl.gif'); background-repeat: no-repeat } /* Нижний левый уголок */
.bottomline div div { background: url('corn_br.gif'); height: 19px;background-position: right; background-repeat: no-repeat } /* Нижний правый уголок */</pre>
<p>Возможности, которые дает такое решение:<br />
1) если у уголков прозрачной является внешняя часть, а не внутренняя, то фон страницы (или родительского блока) может быть неоднородным;<br />
2) фон самого блока может быть градиентным, уголки при этом также остаются градиентными;<br />
3) не накладывается каких-либо ограничений на отступы (margin и padding) и высоту блока с контентом, ими можно управлять свободно;<br />
4) верхняя и нижняя области рядом с уголками не являются &#8220;мертвой зоной&#8221;, как это обычно бывает во многих других решениях, там можно поместить какой-либо текст (например, заголовок вверху и copyright-сообщение внизу), либо организовать &#8220;наползание&#8221; блока с контентом на уголки, поставив ему отрицательные вертикальные поля (margins);<br />
5) несмотря на то, что вместо одного тега становится 7, объем кода увеличивается несущественно: только для трех из них требуется указывать классы. Кроме того, решение легко воспринимается из-за своей полной симметричности, так что почти не страдает читаемость кода.</p>
<p>К недостаткам подхода можно отнести необходимость использовать большое количество фоновых изображений (4 уголка обязательно + 2 или 3 фоновых рисунка, если используется градиент или сложный фон). Однако эта проблема легко решается за счет использования технологии <a href="http://www.xpro.su/archives/110">Data In URIs</a>, описанной ранее.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xpro.su/archives/134/feed</wfw:commentRss>
		</item>
		<item>
		<title>Настройка кеширования в Apache</title>
		<link>http://www.xpro.su/archives/123</link>
		<comments>http://www.xpro.su/archives/123#comments</comments>
		<pubDate>Fri, 10 Apr 2009 12:41:24 +0000</pubDate>
		<dc:creator>4X_Pro</dc:creator>
		
		<category><![CDATA[HTTP]]></category>

		<category><![CDATA[Администрирование]]></category>

		<guid isPermaLink="false">http://www.xpro.su/?p=123</guid>
		<description><![CDATA[По умолчанию Apache настроен так, что кеширование запрещено даже для статического контента. Это означает, что при каждом обращении к сайту заново подгружаются все файлы CSS, JavaScript и картинки, что явно не способствует быстродействию.
Чтобы этого избежать, следует настроить выдачу заголовков Expires (время устаревания контента), ETag (строка, которая изменяется в случае изменения файла) и Cache Control (управление [...]]]></description>
			<content:encoded><![CDATA[<p>По умолчанию Apache настроен так, что кеширование запрещено даже для статического контента. Это означает, что при каждом обращении к сайту заново подгружаются все файлы CSS, JavaScript и картинки, что явно не способствует быстродействию.<br />
Чтобы этого избежать, следует настроить выдачу заголовков Expires (время устаревания контента), ETag (строка, которая изменяется в случае изменения файла) и Cache Control (управление кешированием).<br />
В Apache 2.x это делается с помощью следующих директив:<br />
<span id="more-123"></span></p>
<pre>
# добавление сжатия файлов
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE image/x-icon
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/x-javascript

# обработка "кривых" броузеров
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch Konqueror no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

Header append Vary User-Agent

# разрешение кеширования файлов на стороне клиента
&lt;FilesMatch .*\.(css|js|php|phtml|shtml|html|xml)$&gt;
    Header append Cache-Control private
&lt;/FilesMatch&gt;

# включение заголовка Expires для всех файлов сроком на месяц
ExpiresActive On
ExpiresDefault "access plus 1 month"

# выключение Expires для HTML-файлов и PHP-скриптов
&lt;FilesMatch .*\.(shtml|html|phtml|php)$&gt;
    ExpiresActive Off
&lt;/FilesMatch&gt;

# Выдача заголовка ETag
FileETag MTime Size
</pre>
<p>Для Apache 1.3 с модулем mod_gzip:</p>
<pre>
Header append Vary User-Agent

# разрешение кеширования файлов на стороне клиента
&lt;FilesMatch .*\.(css|js|php|phtml|shtml|html|xml)$&gt;
    Header append Cache-Control private
&lt;/FilesMatch&gt;

# включение заголовка Expires для всех файлов сроком на месяц
ExpiresActive On
ExpiresDefault "access plus 1 month"

# выключение Expires для HTML-файлов и PHP-скриптов
&lt;FilesMatch .*\.(shtml|html|phtml|php)$&gt;
    ExpiresActive Off
&lt;/FilesMatch&gt;

# Выдача заголовка ETag
FileETag MTime Size

# Включение модуля mod_gzip
&lt;IfModule mod_gzip.c&gt;
    mod_gzip_on                   Yes
    mod_gzip_can_negotiate        Yes
    mod_gzip_static_suffix        .gz
    AddEncoding              gzip .gz
    mod_gzip_update_static        No

    mod_gzip_command_version      '/mod_gzip_status'
    mod_gzip_temp_dir             /tmp

    mod_gzip_keep_workfiles       No
    mod_gzip_minimum_file_size    500
    mod_gzip_maximum_file_size    5000000
    mod_gzip_maximum_inmem_size   60000

    mod_gzip_min_http             1000
    mod_gzip_handle_methods       GET POST
    mod_gzip_item_exclude         reqheader  "User-agent: Mozilla/4.0[678]"

    mod_gzip_item_include         file       \.html$
    mod_gzip_item_include         file       \.js$
    mod_gzip_item_include         file       \.css$

# mod_gzip_item_include         file       \.pl$
# mod_gzip_item_include         handler    ^cgi-script$

    mod_gzip_item_include         mime       ^text/html$
    mod_gzip_item_include         mime       ^text/plain$
    mod_gzip_item_include         mime       ^httpd/unix-directory$
    mod_gzip_item_exclude         mime       ^image/
    mod_gzip_dechunk              Yes

    mod_gzip_add_header_count     Yes
&lt;/IfModule&gt;
</pre>
<p>При написании статьи использовались материалы сайта <a href="http://webo.in/articles/all/2009/06-clientside-optimization-vaclavak.ru/">Webo.In</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.xpro.su/archives/123/feed</wfw:commentRss>
		</item>
		<item>
		<title>Обработка текста с тегами pre и code</title>
		<link>http://www.xpro.su/archives/117</link>
		<comments>http://www.xpro.su/archives/117#comments</comments>
		<pubDate>Sat, 04 Apr 2009 11:03:59 +0000</pubDate>
		<dc:creator>4X_Pro</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[обработка текста]]></category>

		<category><![CDATA[регулярные выражения]]></category>

		<guid isPermaLink="false">http://www.xpro.su/?p=117</guid>
		<description><![CDATA[Иногда требуется выполнить какую-либо обработку HTML-кода (например, расставить графические смайлики, выполнить типографирование, убрать лишние пробелы). До тех пор, пока в этом коде нет тегов &#60;pre&#62; и &#60;code&#62;, все очень просто решается обычными регулярными выражениями. Однако при наличии этих тегов возникает необходимость сохранить текст внутри них без каких-либо изменений.
В этом случае подойдет следующее решение: запомнить и [...]]]></description>
			<content:encoded><![CDATA[<p>Иногда требуется выполнить какую-либо обработку HTML-кода (например, расставить графические смайлики, выполнить типографирование, убрать лишние пробелы). До тех пор, пока в этом коде нет тегов &lt;pre&gt; и &lt;code&gt;, все очень просто решается обычными регулярными выражениями. Однако при наличии этих тегов возникает необходимость сохранить текст внутри них без каких-либо изменений.<br />
В этом случае подойдет следующее решение: запомнить и заменить содержимое этих тегов специальными последовательностями, у которых очень мала вероятность встретиться в тексте, провести обработку оставшейся части, после чего провести обратную замену.<br />
Последовательность, на которую производится замена, должна выбираться так, чтобы при обработке она никаким образом не была изменена.<br />
Пример такого кода:<br />
<span id="more-117"></span></p>
<pre>
// замена тегов
$pre_count=preg_match_all('|(
<pre\s*>.*?</pre\s*>)|is',$text,$pre_matches);
for ($i=0; $i<$pre_count; $i++) $text=str_replace($pre_matches[0][$i],'<PRE|'.$i.'|'.$key.'>',$text);
$code_count=preg_match_all('|(<code\s*>.*?</code\s*>)|is',$text,$code_matches);
for ($i=0; $i<$code_count; $i++) $text=str_replace($code_matches[0][$i],'<CODE|'.$i.'|'.$key.'>',$text);

// здесь будет производиться обработка текста в переменной $text регулярными выражениями

	// восстановление тегов
for ($i=0; $i<$pre_count; $i++) $text=str_replace('<PRE|'.$i.'|'.$key.'>',$pre_matches[0][$i],$text);
for ($i=0; $i<$code_count; $i++) $text=str_replace('<CODE|'.$i.'|'.$key.'>',$pre_matches[0][$i],$text);
</pre>
<p>В данном примере содержимое тега pre заменяется на последовательность вида &lt;PRE|номер|случайная_строка&gt;, где номер &#8212; порядковый номер тега pre (так как в тексте он может встретиться несколько раз), случайная строка &#8212; MD-хеш случайного числа (содержит только 16-ичные цифры, что минимизирует вероятность их некорректной обработки).<br />
Важно: номер последовательности не должен стоять в конце (или за ним должен быть какой-то ограничивающий символ), так как в противном случае последовательности с номерами больше 9 начнут обрабатываться некорректно (при обратной замене вместо них будет вставляться первая или нулевая последовательность). Кроме того, предолженный код не будет работать с вложенными тегами.<br />
Если в обработчике предполагается анализ и проверка правильности HTML-тегов, то целесобразно привести заменяющую строку к виду, напоминающему корректный HTML-тег, например: &lt;pre num=&#8221;номер&#8221; code=&#8221;случ_строка&#8221;&gt;&lt;/pre&gt;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xpro.su/archives/117/feed</wfw:commentRss>
		</item>
	</channel>
</rss>

