<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SimpleCoding.org &#187; htaccess</title>
	<atom:link href="http://www.simplecoding.org/category/htaccess/feed" rel="self" type="application/rss+xml" />
	<link>http://www.simplecoding.org</link>
	<description>Блог о программировании</description>
	<lastBuildDate>Sun, 25 Jul 2010 20:00:16 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<link rel="http://api.friendfeed.com/2008/03#sup" xmlns="http://www.w3.org/2005/Atom" type="application/json" href="http://friendfeed.com/api/public-sup.json#d217526a2c"/>		<item>
		<title>Боремся с Magic Quotes</title>
		<link>http://www.simplecoding.org/boremsya-s-magic-quotes.html</link>
		<comments>http://www.simplecoding.org/boremsya-s-magic-quotes.html#comments</comments>
		<pubDate>Sat, 12 Sep 2009 07:35:25 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Hosting]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[htaccess]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=902</guid>
		<description><![CDATA[На днях я столкнулся с довольно неприятной ситуацией. Скрипт, который прекрасно работал на локальном сервере начал выдавать ошибки на сервере хостера.
Проблема оказалась мелкой и я все быстро исправил, но эта ситуация напомнила мне о законе подлости. Как только забываешь о тестировании – скрипты сразу перестают работать. Не зависимо от того, насколько они простые.  
В [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_903" class="wp-caption alignnone" style="width: 310px"><img src="http://www.simplecoding.org/wp-content/uploads/2009/09/php_magic_quotes.png" alt="php magic quotes" title="php magic quotes" width="300" height="145" class="size-full wp-image-903" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>На днях я столкнулся с довольно неприятной ситуацией. Скрипт, который прекрасно работал на локальном сервере начал выдавать ошибки на сервере хостера.</p>
<p>Проблема оказалась мелкой и я все быстро исправил, но эта ситуация напомнила мне о законе подлости. <strong>Как только забываешь о тестировании – скрипты сразу перестают работать</strong>. Не зависимо от того, насколько они простые. <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>В данном случае дело было во включенных <strong>Magic Quotes</strong> (волшебных кавычках, хорошее название, появляются как по волшебству там, где не надо <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ).</p>
<p>Вообще-то, использование  Magic Quotes не рекомендуемая практика.</p>
<p>В соответствующем разделе <a href="http://ua2.php.net/manual/en/security.magicquotes.php"><acronym title="PHP: Hypertext Preprocessor">PHP</acronym> manual</a> ясно об этом сказано.</p>
<blockquote><p><strong>Warning</strong></p>
<p>This feature has been DEPRECATED as of <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> 5.3.0 and REMOVED as of <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> 6.0.0. Relying on this feature is highly discouraged.</p></blockquote>
<blockquote><p><strong>Предупреждение</strong></p>
<p>Эта возможность считается устаревшей начиная с <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> 5.3.0 и будет удалена начиная с <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> 6.0.0. Рассчитывать на эту возможность крайне не рекомендуется.</p></blockquote>
<p>Кратко поясню смысл этой функции. Она перехватывает данные, которые получает скрипт (массивы $_POST, $_GET и т.д.) и экранирует в них специальные символы.</p>
<p>Была разработана для защиты от хакерских атак вроде <strong><acronym title="Structured Query Language">SQL</acronym> Injection</strong>.</p>
<p>Но на практике от нее больше проблем, чем пользы.<br />
<span id="more-902"></span><br />
Во-первых, 100% защиты она не обеспечивает. Т.е. вам все равно <strong>нужно самостоятельно проверять полученные данные</strong> (их тип, диапазон допустимых значений и т.п.). К тому же экранирование символов выполняется автоматически практически всеми библиотеками для работы с БД.</p>
<p>Во-вторых, часто нужны <strong>не</strong> экранированные данные.</p>
<p>Например, в моем случае ситуация была такой.</p>
<p>1) Клиент (браузер) передавал строку в формате <strong>json</strong>.<br />
2) <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> при включенной Magic Quotes экранировал спец. символы.<br />
3) функция <code>json_decode</code> возвращала NULL. <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Почему хостеры включают Magic Quotes – вопрос отдельный. Может быть, хотят немного подстраховаться от начинающих разработчиков <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Или есть какие-то другие причины. Но в любом случае, вы можете легко ее отключить.</p>
<p>Посмотреть текущие настройки можно с помощью <code>phpinfo()</code>. (если Magic Quotes включена, в разделе  <code>Configure Command</code>  будет строка  <code>--enable-magic-quotes</code>).</p>
<p>Для отключения создаем в папке со скриптами файл <code>.htaccess</code> с одной строчкой.</p>
<p><code>php_flag magic_quotes_gpc Off</code></p>
<p>Отключает Magic quotes для входящих данных из массивов GET/POST/Cookie.</p>
<p>Или добавляем эту же строчку в существующий <code>.htaccess</code>.</p>
<p><em>Примечание</em>. Естественно, Magic Quotes можно отключить и в php.ini, но на shared хостинге у вас к нему доступа нет.</p>
<p>Подробнее об отключении Magic quotes можно почитать в <a href="http://ua2.php.net/manual/en/security.magicquotes.disabling.php"><acronym title="PHP: Hypertext Preprocessor">PHP</acronym> Manual</a>.</p>
<p>Кстати, в нем есть пример функции, которая выполняет обратную операцию (удаляет слеши) &#8211; это на случай если хостер отключил поддержку <code>.htaccess</code>. Но, честно говоря, в такой ситуации я бы подумал о смене хостера.</p>
<p>До встречи!</p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=902&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/boremsya-s-magic-quotes.html/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>PHP скрипт: ToDo с картинками</title>
		<link>http://www.simplecoding.org/php-skript-todo-s-kartinkami.html</link>
		<comments>http://www.simplecoding.org/php-skript-todo-s-kartinkami.html#comments</comments>
		<pubDate>Thu, 13 Aug 2009 19:01:21 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[htaccess]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=885</guid>
		<description><![CDATA[Уделяете ли вы внимание организации своей работы?
Много ли у вас &#034;мелких&#034; дел, о которых вы регулярно забываете?
Вроде бы простые вопросы, но для многих людей (и я не исключение) организация работы – это актуальная проблема.
Хуже всего, когда нужно сделать много «мелких» дел, которые не занимают много времени, но обязательно должны быть выполнены вовремя&#8230; и держать в [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_886" class="wp-caption alignnone" style="width: 320px"><img src="http://www.simplecoding.org/wp-content/uploads/2009/08/simple_tasks.png" alt="simple tasks" title="simple tasks" width="310" height="129" class="size-full wp-image-886" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>Уделяете ли вы внимание организации своей работы?<br />
Много ли у вас &#034;мелких&#034; дел, о которых вы регулярно забываете?</p>
<p>Вроде бы простые вопросы, но для многих людей (и я не исключение) <strong>организация работы</strong> – это актуальная проблема.</p>
<p>Хуже всего, когда нужно сделать много «мелких» дел, которые не занимают много времени, но обязательно должны быть выполнены вовремя&#8230; и держать в голове их все просто невозможно.</p>
<p>Естественно, разработчики реагируют на потребности рынка, и на сегодняшний день создано множество программ-органайзеров, различных напоминалок и т.п.<br />
Примеры создания ToDo списков часто приводят в учебниках по программированию.</p>
<p>Я решил не оставаться в стороне и сделал <strong>собственный вариант такого ToDo списка, естественно, с некоторыми дополнительными возможностями</strong>.</p>
<p>Кстати, скрипт называется <strong>SimpleTasks</strong>.</p>
<p>Главная особенность – <strong>возможность указывать состояние выполнения задач</strong>. При этом используется специальная система обозначений.<br />
<span id="more-885"></span></p>
<div id="attachment_887" class="wp-caption alignnone" style="width: 490px"><img src="http://www.simplecoding.org/wp-content/uploads/2009/08/symbols_for_paper_notebook_with_description.png" alt="symbols for paper notebook with description" title="symbols for paper notebook with description" width="480" height="192" class="size-full wp-image-887" /><p class="wp-caption-text"> </p></div>
<p>Систему обозначений придумал не я. <del datetime="2009-08-14T13:47:28+00:00">Но, к сожалению, не могу найти первоисточник</del> (UPD. Огромное спасибо <a href="http://i-smarty.com">Smarty</a> за ссылку на <a href="http://font.is/?p=790">оригинал</a>). Предназначена она для использования с бумажным блокнотом и довольно удобная. Во всяком случае, читать такой список задач становится намного легче. Взгляд сразу отбрасывает выполненные задачи.</p>
<p>Но <strong>возможности web приложений намного шире</strong>, чем у обычного ежедневника. Например, можно сделать систему фильтров и легко работать с большими списками задач.</p>
<p>В общем, я написал небольшое web приложение, использующее эту систему обозначений.</p>
<p>Если есть желание, можете поиграться с ним (логин admin@todo.loc, пароль password).</p>
<p><a href="http://demosites.org.ua/simpletasks/"><img src="http://www.simplecoding.org/wp-content/themes/three_cols/images/demo_btn_green.png" alt="демонстрационный пример" /></a></p>
<p>Или скачать архив и установить на своем сервере (инструкция в архиве).</p>
<p><a href='http://www.simplecoding.org/wp-content/uploads/2009/08/simpletasks.zip'><img src="http://www.simplecoding.org/wp-content/themes/three_cols/images/download_btn_blue.png" alt="архив с исходным кодом" /></a></p>
<p><strong>Принцип работы.</strong></p>
<p><strong>Создание новой записи.</strong><br />
Кликаем по ссылке &#034;Новая запись&#034; (справа в верхней части страницы) и в открывшемся окне вводим данные записи.<br />
При клике по полю &#034;Дата&#034; будет открыт календарь. Т.е. ввести дату в неправильном формате довольно проблематично.</p>
<p><strong>Редактирование.</strong><br />
Клик или двойной клик на соответствующем поле позволяет изменить его. Открываетеся либо диалог, либо inline редактор.</p>
<p><strong>Удаление.</strong><br />
Кликните по картинке с изображением крестика в соответствующей строке и подтвердите удаление.</p>
<p><strong>Фильтры.</strong><br />
Позволяют выбрать задачи с определенным состоянием в указанном диапазоне дат.</p>
<p>Ссылки в верхнем меню дублируют наиболее распространенные (на мой взгляд) фильтры.</p>
<p><strong>Состояние работ.</strong><br />
На данный момент это только бета версия.<br />
Еще не доделана локализация. Доступен только один вариант &#8211; русский.<br />
Возможно, отсутствуют некоторые сообщения об ошибках.</p>
<p>Скорее всего, некоторые функции будут дорабатываться.</p>
<p><strong>И я очень хочу услышать ваше мнение!<br />
</strong><br />
Прежде всего, меня интересуют такие вопросы.</p>
<p>1) Есть ли смысл делать подобное приложение многопользовательским? Т.е. технически это совсем не сложно, вопрос в том будет ли кто-то в рамках небольшой организации использовать такое приложение для хранения заметок сотрудников?</p>
<p>2) Какие еще функии вы бы добавили?</p>
<p>3) Может кто-то видел хороший тьюториал о локализации <acronym title="JavaScript">JS</acronym> приложений? (Сейчас я ориентируюсь на то, как сделана локализация в jQuery UI).</p>
<p><strong>P.S.</strong> На этих выходных я уезжаю догуливать остатки отпуска, поэтому прошу прощения, если не сразу отвечу на ваши комментарии. Я обязательно их прочитаю&#8230; даже спаммерские <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=885&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/php-skript-todo-s-kartinkami.html/feed</wfw:commentRss>
		<slash:comments>60</slash:comments>
		</item>
		<item>
		<title>JavaScript библиотеки для создания графиков</title>
		<link>http://www.simplecoding.org/javascript-biblioteki-dlya-sozdaniya-grafikov.html</link>
		<comments>http://www.simplecoding.org/javascript-biblioteki-dlya-sozdaniya-grafikov.html#comments</comments>
		<pubDate>Sat, 25 Apr 2009 16:33:23 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[htaccess]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=815</guid>
		<description><![CDATA[Сегодня я продолжу рассказ о создании и использовании графиков на web ресурсах.
В предыдущих статьях речь шла об использовании для этих целей flash библиотек (Графики своими руками – Open Flash Chart 2) и внешних сервисов (Графики от Google и PHP библиотеки для работы с ними).
В принципе, на этом можно было бы остановиться, но судя по реакции [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_816" class="wp-caption alignnone" style="width: 310px"><img src="http://www.simplecoding.org/wp-content/uploads/2009/04/javascript_flot_graph.png" alt="javascript flot graph" title="javascript flot graph" width="300" height="178" class="size-full wp-image-816" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>Сегодня я продолжу <strong>рассказ о создании и использовании графиков на web ресурсах</strong>.</p>
<p>В предыдущих статьях речь шла об использовании для этих целей <strong>flash библиотек</strong> (<a href="http://www.simplecoding.org/grafiki-svoimi-rukami-open-flash-chart-2.html">Графики своими руками – Open Flash Chart 2</a>) и внешних сервисов (<a href="http://www.simplecoding.org/grafiki-ot-google-i-php-biblioteki-dlya-raboty-s-nimi.html">Графики от Google и <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> библиотеки для работы с ними</a>).</p>
<p>В принципе, на этом можно было бы остановиться, но судя по реакции в комментариях, я пропустил ещё один очень интересный вариант создания графиков. Речь, конечно, об использовании <strong>JavaScript</strong>.</p>
<p>Рассмотрим достоинства и недостатки этого варианта.</p>
<p><strong>Достоинства</strong>.</p>
<p>1) <strong>Минимальные затраты на трафик</strong>. Передать нужно только саму библиотеку (обычно размер не превышает 100 кБ (без сжатия)) и данные для построения графика.</p>
<p>2) <strong>Минимальная нагрузка на сервер</strong>. Отрисовка графика выполняется браузером. Сервер должен только отправить массив с точками, по которым будет построен график.</p>
<p>3) <strong>Простота использования</strong>. Достигается за счет готовых библиотек.</p>
<p><strong>Недостатки</strong>.</p>
<p>1) Возможны <strong>проблемы совместимости</strong> с некоторыми браузерами. С этими проблемами знакомы все web мастера. Но, должен отметить, что разработчики библиотек неплохо с ними справляются.</p>
<p>2) <strong>Дополнительная нагрузка на компьютер пользователя</strong>. Достаточно спорный момент. Вряд ли обычный пользователь заметит время, за которое будет создан один простой график. Но если графиков десятки и для их создания используются тысячи точек, то время создания такой страницы может существенно возрасти. В общем, тут многое зависит от вас.</p>
<p>Теперь перейдем к практической части.<br />
<span id="more-815"></span><br />
На сегодняшний день JavaScript библиотек для создания графиков довольно много. Но принципы их использования практически одинаковые, поэтому пример приведу я только для одной.</p>
<p>Библиотека называется <a href="http://code.google.com/p/flot/">Flot</a>.</p>
<p>Для начала <strong>определимся с задачей</strong>.</p>
<p>Допустим, у нас есть <strong><acronym title="PHP: Hypertext Preprocessor">PHP</acronym> скрипт</strong>, который получает данные, которые нужно показать на графике. И <strong><acronym title="HyperText Markup Language">HTML</acronym> страница</strong> на которой мы должны разместить график.</p>
<p>Начнем с разметки страницы.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;</span>?xml <span class="kw3">version</span>=<span class="st0">&quot;1.0&quot;</span> encoding=<span class="st0">&quot;UTF-8&quot;</span>?<span class="kw2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc0">&lt;!DOCTYPE html PUBLIC &quot;-//<acronym title="World Wide Web Consortium">W3C</acronym>//<acronym title="Document Type Definition">DTD</acronym> <acronym title="eXtensible HyperText Markup Language">XHTML</acronym> 1.0 Strict//EN&quot;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc0"> &nbsp; &nbsp; &nbsp; &nbsp;&quot;http://www.w3.org/TR/xhtml1/<acronym title="Document Type Definition">DTD</acronym>/xhtml1-strict.dtd&quot;&gt;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;html</span> xmlns=<span class="st0">&quot;http://www.w3.org/1999/xhtml&quot;</span> xml:<span class="kw3">lang</span>=<span class="st0">&quot;en&quot;</span> <span class="kw3">lang</span>=<span class="st0">&quot;en&quot;</span><span class="kw2">&gt;</span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;head&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc2"><span class="kw2">&lt;title&gt;</span></span>Тестирование библиотеки Flot<span class="sc2"><span class="kw2">&lt;/title&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc2"><span class="kw2">&lt;meta</span> <span class="kw3">http-equiv</span>=<span class="st0">&quot;content-type&quot;</span> <span class="kw3">content</span>=<span class="st0">&quot;text/html;charset=utf-8&quot;</span> /<span class="kw2">&gt;</span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="sc2"><span class="kw2">&lt;meta</span> <span class="kw3">http-equiv</span>=<span class="st0">&quot;Content-Style-Type&quot;</span> <span class="kw3">content</span>=<span class="st0">&quot;text/css&quot;</span> /<span class="kw2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc2"><span class="kw2">&lt;meta</span> <span class="kw3">name</span>=<span class="st0">&quot;description&quot;</span> <span class="kw3">content</span>=<span class="st0">&quot;Использование библиотеки Flot&quot;</span> /<span class="kw2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc2"><span class="kw2">&lt;meta</span> <span class="kw3">name</span>=<span class="st0">&quot;keywords&quot;</span> <span class="kw3">content</span>=<span class="st0">&quot;flot, javascript, график&quot;</span> /<span class="kw2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;/head&gt;</span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;body&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;div</span> <span class="kw3">id</span>=<span class="st0">&quot;my_graph&quot;</span> <span class="kw3">style</span>=<span class="st0">&quot;width:500px; height:300px&quot;</span><span class="kw2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;/div&gt;</span></span><span class="sc2"><span class="coMULTI">&lt;!&#8211; end of my_graph &#8211;&gt;</span></span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;p&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; Подробное описание этого примера в статье <span class="sc2"><span class="kw2">&lt;a</span> <span class="kw3">href</span>=<span class="st0">&quot;&quot;</span><span class="kw2">&gt;</span></span><span class="sc2"><span class="kw2">&lt;/a&gt;</span></span>.</div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;/p&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="sc2"><span class="kw2">&lt;script</span> <span class="kw3">type</span>=<span class="st0">&quot;text/javascript&quot;</span> <span class="kw3">src</span>=<span class="st0">&quot;jquery.js&quot;</span><span class="kw2">&gt;</span></span><span class="sc2"><span class="kw2">&lt;/script&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;script</span> <span class="kw3">type</span>=<span class="st0">&quot;text/javascript&quot;</span> <span class="kw3">src</span>=<span class="st0">&quot;jquery.flot.js&quot;</span><span class="kw2">&gt;</span></span><span class="sc2"><span class="kw2">&lt;/script&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="coMULTI">&lt;!&#8211;[if <acronym title="Internet Explorer">IE</acronym>]&gt;</span></div>
</li>
<li class="li1">
<div class="de1"></span><span class="sc2"><span class="kw2">&lt;script</span> <span class="kw3">type</span>=<span class="st0">&quot;text/javascript&quot;</span> <span class="kw3">src</span>=<span class="st0">&quot;excanvas.js&quot;</span><span class="kw2">&gt;</span></span><span class="sc2"><span class="kw2">&lt;/script&gt;</span></span><span class="sc2"><span class="kw2">&lt;</span>!<span class="br0">&#91;</span>endif<span class="br0">&#93;</span>&#8211;<span class="kw2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;script</span> <span class="kw3">type</span>=<span class="st0">&quot;text/javascript&quot;</span> <span class="kw3">src</span>=<span class="st0">&quot;main.js&quot;</span><span class="kw2">&gt;</span></span><span class="sc2"><span class="kw2">&lt;/script&gt;</span></span></div>
</li>
<li class="li2">
<div class="de2"><span class="sc2"><span class="kw2">&lt;/body&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc2"><span class="kw2">&lt;/html&gt;</span></span></div>
</li>
</ol>
</div>
<p>Как видите, это обычная страница, внутри которой находится блок <code>div</code>, предназначенный для размещения нашего графика (строки 18-19). В <strong><acronym title="Cascading Style Sheets">CSS</acronym> стилях</strong> этого блока нужно обязательно указать его размеры (<code>width</code>, <code>height</code>).</p>
<p>Кроме того, в конце страницы мы подключили файлы библиотеки (строки 25-27).</p>
<p>Т.к. библиотека Flot (<code>jquery.flot.js</code>) является плагином к <a href="http://jquery.com/">jQuery</a>, то первой мы подключаем её. Третий файл (<code>excanvas.js</code>) нужен для поддержки <strong><acronym title="Internet Explorer 6">IE6</acronym></strong>.</p>
<p>В строке 30 мы подключаем JavaScript файл (<code>main.js</code>), который будет получать данные от сервера и рисовать график.</p>
<p>Рассмотрим его подробнее.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">$<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">//получаем данные для графика (с помощью <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> запроса)</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; $.<span class="me1">get</span><span class="br0">&#40;</span>document.<span class="me1">location</span>.<span class="me1">href</span> + <span class="st0">&quot;datasrc.php&quot;</span>, <span class="kw2">null</span>, <span class="kw2">function</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//строим график</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> graphData = <span class="kw1">eval</span><span class="br0">&#40;</span><span class="st0">&quot;(&quot;</span> + data + <span class="st0">&quot;)&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; $.<span class="me1">plot</span><span class="br0">&#40;</span>$<span class="br0">&#40;</span><span class="st0">&quot;#my_graph&quot;</span><span class="br0">&#41;</span>, graphData, <span class="br0">&#123;</span> yaxis: <span class="br0">&#123;</span>max: <span class="nu0">6</span>, min: <span class="nu0">-6</span><span class="br0">&#125;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>Как видите, тут все предельно просто.</p>
<p>1) Получаем данные (с помощью Ajax запроса).</p>
<p>2) Для передачи данных я выбрал JSON формат, т.к. он позволяют максимально упростить скрипты.</p>
<p>3) Строим график с помощью функции plot. В её первом параметре передаём id блока, в котором будет размещен график. Во втором – данные, полученные от серверного скрипта. В третьем – настройки графика (я указал только минимальное и максимальное значение по вертикальной оси).</p>
<p>Теперь <strong>переходим к сервреной части</strong>.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//Тут может быть код для получения данных из базы данных</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//В этом примере мы создадим обычный массив с координатами точек</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$points1</span> = <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">0</span>,<span class="nu0">1</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">1</span>,<span class="nu0">3</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">2</span>,<span class="nu0">-4</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">3</span>,<span class="nu0">2</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">4</span>,<span class="nu0">0.5</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">5</span>,<span class="nu0">0.7</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">6</span>,<span class="nu0">-1</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">7</span>,<span class="nu0">4</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">8</span>,<span class="nu0">2</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$points2</span> = <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">0</span>,<span class="nu0">-1</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">1</span>,<span class="nu0">-3</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">2</span>,<span class="nu0">4</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">3</span>,<span class="nu0">-2</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">4</span>,<span class="nu0">-0.5</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">5</span>,<span class="nu0">-0.7</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">6</span>,<span class="nu0">1</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">7</span>,<span class="nu0">-4</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">8</span>,<span class="nu0">-2</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="co1">//массив с настройками графика</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$graph</span> = <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;color&#039;</span>=&gt;<span class="st0">&#039;rgb(255, 98, 0)&#039;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; , <span class="st0">&#039;data&#039;</span>=&gt;<span class="re0">$points1</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; , <span class="st0">&#039;label&#039;</span>=&gt;<span class="st0">&#039;Линия 1&#039;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; , <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#039;color&#039;</span>=&gt;<span class="st0">&#039;rgb(18, 143, 52)&#039;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; , <span class="st0">&#039;data&#039;</span>=&gt;<span class="re0">$points2</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; , <span class="st0">&#039;label&#039;</span>=&gt;<span class="st0">&#039;Линия 2&#039;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> json_encode<span class="br0">&#40;</span><span class="re0">$graph</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// end of datasrc.php</span></div>
</li>
</ol>
</div>
<p>Этот скрипт просто создает массив с данными графика, преобразует в <strong>JSON</strong> формат и отправляет браузеру.</p>
<p>Обратите внимание на запись данных в массив. Массив <code>$graph</code> содержит 2 вложенных массива, каждый из которых в свою очередь содержит все данные, необходимые для создания <strong>одной линии</strong> на графике. Прежде всего, это координаты точек (элемент <code>data</code>), цвет линии (<code>color</code>), подпись (<code>label</code>).</p>
<p>Вообще-то существует десяток других параметров. Но чтобы упростить пример я их пропустил. Подробнее почитать об использовании этой библиотеки вы всегда сможете в документации.</p>
<p><strong>Live Demo</strong></p>
<p>Посмотреть, как выглядит этот график можно <a href="http://demosites.org.ua/flot/">здесь</a>.</p>
<p><strong>Скачать</strong></p>
<p>Кроме того, если есть желание поэкспериментировать вы можете скачать <a href='http://www.simplecoding.org/wp-content/uploads/2009/04/flot.zip'>архив с примером</a>.</p>
<p>В заключение приведу небольшой <strong>список JavaScript библиотек для создания графиков</strong>.</p>
<p><a href="http://www.jscharts.com/"><acronym title="JavaScript">JS</acronym> charts</a><br />
<a href="http://code.google.com/p/jqplot/">jqplot</a><br />
<a href="http://www.liquidx.net/plotkit/">PlotKit</a><br />
<a href="http://membres-liglab.imag.fr/donsez/cours/exemplescourstechnoweb/js_graphimg/">JavaScript Graph Builder</a><br />
<a href="http://raphaeljs.com/">Raphaël</a><br />
<a href="http://omnipotent.net/jquery.sparkline/">jQuery Sparklines</a></p>
<p><strong>Небольшое дополнение</strong>.</p>
<p>В несжатом варианте используемые здесь JavaScript библиотеки довольно объемные. Поэтому я упаковал их архиватором <a href="http://www.7-zip.org/">7-zip</a> и добавил в папку с этим примером <code>.htaccess</code> с таким содержимым.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&lt;IfModule mod_rewrite.c&gt;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; RewriteEngine On
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; AddEncoding gzip .gz
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; RewriteCond %{HTTP:Accept-encoding} gzip
</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; RewriteCond %{REQUEST_FILENAME}.gz -f
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; RewriteRule ^(.*)$ $1.gz [QSA,L]
</div>
</li>
<li class="li1">
<div class="de1">&lt;/IfModule&gt;</div>
</li>
</ol>
</div>
<p>Теперь посетителю будет отправляться заархивированный вариант библиотеки.</p>
<p>Подробнее почитать о принципе работы .htaccess можно в статье <a href="http://www.simplecoding.org/uvelichivaem-skorost-zagruzki-web-stranic.html">Увеличиваем скорость загрузки web страниц</a>.</p>
<p>Как всегда, буду рад услышать ваше мнение в комментариях <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=815&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/javascript-biblioteki-dlya-sozdaniya-grafikov.html/feed</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
		<item>
		<title>Bug Tracker: установка фреймворка и создание базы данных (часть вторая)</title>
		<link>http://www.simplecoding.org/bug-tracker-ustanovka-frejmvorka-i-sozdanie-bazy-dannyx-chast-vtoraya.html</link>
		<comments>http://www.simplecoding.org/bug-tracker-ustanovka-frejmvorka-i-sozdanie-bazy-dannyx-chast-vtoraya.html#comments</comments>
		<pubDate>Sun, 01 Mar 2009 18:46:14 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[htaccess]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=776</guid>
		<description><![CDATA[Сегодня я продолжаю рассказывать о разработке собственной системы отслеживания ошибок. В прошлой статье только вкратце была описана общая идея и возможности, а также показан предварительный эскиз приложения.
Но прежде чем переходить к основной теме, хочу поблагодарить всех комментаторов и особенно AmdY, Big_Shark и Алексея Качаева за советы!
Первоначально я планировал доделать приложение полностью, и только потом опубликовать [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_777" class="wp-caption alignnone" style="width: 287px"><img src="http://www.simplecoding.org/wp-content/uploads/2009/03/bug_tracker_logo_part2.png" alt="bug_tracker_logo_part2" title="bug_tracker_logo_part2" width="277" height="148" class="size-full wp-image-777" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>Сегодня я продолжаю рассказывать о разработке собственной <strong>системы отслеживания ошибок</strong>. В <a href="http://www.simplecoding.org/sozdaem-sobstvennuyu-sistemu-otslezhivaniya-oshibok-na-php.html">прошлой статье</a> только вкратце была описана общая идея и возможности, а также показан предварительный эскиз приложения.</p>
<p>Но прежде чем переходить к основной теме, хочу поблагодарить всех комментаторов и особенно <a href="http://amdy.su/">AmdY</a>, <strong>Big_Shark</strong> и <a href="http://www.kachayev.ru/">Алексея Качаева</a> за советы!</p>
<p>Первоначально я планировал доделать приложение полностью, и только потом опубликовать этот цикл постов. Но так получается даже лучше. Всегда есть шанс, что читатели найдут недостатки, и мне не придется переделывать все приложение чтобы их исправить <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>В прошлый раз с инструментами мы определились (используем <strong><acronym title="PHP: Hypertext Preprocessor">PHP</acronym></strong>, фреймворк <a href="http://codeigniter.com/">CodeIgniter</a>, <strong>MySQL</strong> и <a href="http://jquery.com/">jQuery</a>).</p>
<p>Сейчас нам нужно их <strong>установить и настроить</strong>.<br />
<span id="more-776"></span><br />
Я предполагаю, что <strong>web сервер</strong>, <strong><acronym title="PHP: Hypertext Preprocessor">PHP</acronym></strong> и <strong>MySQL</strong> у вас уже настроены, поэтому нам нужно только скачать <strong>CodeIgniter</strong> и <strong>jQuery</strong>. После этого распаковываем архивы в какую-нибудь папку на сервере. В результате должна получиться примерно следующая структура папок.</p>
<pre>index.php
.htaccess
system/
js/
	jquery-1.3.2.min.js
css/</pre>
<p>Файл <code>index.php</code> и папка <code>system</code> – из дистрибутива <strong>CodeIgniter</strong>.</p>
<p><code>.htaccess</code> – самый обычный. Сразу приведу его содержимое.</p>
<pre>&lt;IfModule mod_rewrite.c&gt;
	RewriteEngine On
	RewriteBase /

	RewriteCond %{REQUEST_URI} ^system.*
	RewriteRule ^(.*)$ /index.php?/$1 [L]

	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteCond %{REQUEST_FILENAME} !-d
	RewriteCond $1 !^(index\.php|images|robots\.txt|css|js)
	RewriteRule ^(.*)$ index.php?/$1 [L]
&lt;/IfModule&gt;

&lt;IfModule !mod_rewrite.c&gt;
	ErrorDocument 404 /index.php
&lt;/IfModule&gt;</pre>
<p>Основное его назначение – автоматически <strong>подставлять index.php в ссылки</strong>. Т.е. ссылка вида</p>
<p><code>bugtracker.local/bugtracker/page/2</code></p>
<p>будет преобразована в </p>
<p><code>bugtracker.local/index.php/bugtracker/page/2</code></p>
<p>При этом преобразование происходит, только если указанного в <acronym title="Uniform Resource Locator">URL</acronym> файла на самом деле не существует. Т.е. если запрос будет к <code>js</code> или <code>css</code> файлу, то <code>index.php</code> подставляться не будет.</p>
<p>Кстати, если вы хотите, чтобы приложение находилось в какой-нибудь папке (например, <code>mysite.domen/bugtracker/</code>), то нужно будет изменить параметр <code>RewriteBase</code>.</p>
<p>На настройке <strong>CodeIgniter</strong> подробно останавливаться не буду. Просто перечислю файлы, в которые нужно внести изменения.</p>
<p>Все конфигурационные файлы находятся в папке <code>system/application/</code>.</p>
<p><code>autoload.php</code> – загружаем библиотеку для работы с базой данных и <acronym title="Uniform Resource Locator">URL</acronym> хелпер</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$autoload</span><span class="br0">&#91;</span><span class="st0">&#039;libraries&#039;</span><span class="br0">&#93;</span> = <span class="kw3">array</span><span class="br0">&#40;</span><span class="st0">&#039;database&#039;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$autoload</span><span class="br0">&#91;</span><span class="st0">&#039;helper&#039;</span><span class="br0">&#93;</span> = <span class="kw3">array</span><span class="br0">&#40;</span><span class="st0">&#039;url&#039;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p><code>config.php</code> – здесь указываем адрес приложения, например,</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$config</span><span class="br0">&#91;</span><span class="st0">&#039;base_url&#039;</span><span class="br0">&#93;</span> = <span class="st0">&quot;http://bugtracker.local/&quot;</span>;</div>
</li>
</ol>
</div>
<p>и добавляем ещё один параметр</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$config</span><span class="br0">&#91;</span><span class="st0">&#039;bugs_per_page&#039;</span><span class="br0">&#93;</span> = <span class="nu0">5</span>;</div>
</li>
</ol>
</div>
<p>Как несложно догадаться его значение определяет количество записей о багах на странице.</p>
<p><code>routes.php</code> – тут нужно указать только название контроллера, который будет использоваться по-умолчанию. Я решил его называть <code>bugtracker</code>.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$route</span><span class="br0">&#91;</span><span class="st0">&#039;default_controller&#039;</span><span class="br0">&#93;</span> = <span class="st0">&quot;bugtracker&quot;</span>;</div>
</li>
</ol>
</div>
<p><code>database.php</code> – здесь заполняем массив с параметрами подключения к базе данных.</p>
<p><em>Примечание</em>. Подробнее о настройке фреймворка можно почитать в статье «<acronym title="PHP: Hypertext Preprocessor">PHP</acronym> framework CodeIgniter. Установка и настройка.»</p>
<p>Теперь <strong>переходим к созданию базы данных</strong>.</p>
<p>Нам потребуются три таблицы:</p>
<p>1) <strong>bugs</strong> – используется для хранения информации о найденных багах и комментариях к ним.</p>
<p>Поля:<br />
<code>id</code> – первичный ключ;<br />
<code>title</code> – заголовок;<br />
<code>uname</code> – имя пользователя, который оставил сообщение;<br />
<code>categoryid</code> – id категрии к которой относится баг (должно совпадать с соответствующим полем в таблице <code>categories</code>);<br />
<code>description</code> – описание бага;<br />
<code>status</code> – здесь будет храниться информация о состоянии бага (по-умолчанию, «не исправлено»);<br />
<code>replyto</code> – это поле устанавливает связь между багами и комментариями к ним (подробнее на этом мы остановимся чуть позже).</p>
<p>2) <strong>categories</strong> – список категорий.</p>
<p>Поля:<br />
<code>id</code> – первичный ключ;<br />
<code>link</code> – ссылка на категорию (латинскими буквами);<br />
<code>name</code> – названии категории.</p>
<p>3) <strong>users</strong> – информация о пользователях. В данном случае этими пользователями будут только администраторы баг трекера. Оставлять сообщения и комментарии сможет кто угодно без авторизации.</p>
<p><code>id</code> – первичный ключ;<br />
<code>name</code> – имя пользователя;<br />
<code>pass</code> – пароль.</p>
<p>Теперь посмотрите на запросы, которые создают эти таблицы.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> <span class="st0">`bugs`</span> <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">`id`</span> int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">`title`</span> varchar<span class="br0">&#40;</span><span class="nu0">300</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">`uname`</span> varchar<span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="st0">`categoryid`</span> int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">`description`</span> text <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">`status`</span> varchar<span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">DEFAULT</span> <span class="st0">&#039;не исправлено&#039;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">`replyto`</span> int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> &nbsp;<span class="br0">&#40;</span><span class="st0">`id`</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">KEY</span> <span class="st0">`replyto`</span> <span class="br0">&#40;</span><span class="st0">`replyto`</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span> ENGINE=InnoDB &nbsp;<span class="kw1">DEFAULT</span> CHARSET=utf8 <span class="kw1">AUTO_INCREMENT</span>=<span class="nu0">1</span> ;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ALTER</span> <span class="kw1">TABLE</span> <span class="st0">`bugs`</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">ADD</span> CONSTRAINT <span class="st0">`bugs_ibfk_1`</span> <span class="kw1">FOREIGN</span> <span class="kw1">KEY</span> <span class="br0">&#40;</span><span class="st0">`replyto`</span><span class="br0">&#41;</span> <span class="kw1">REFERENCES</span> <span class="st0">`bugs`</span> <span class="br0">&#40;</span><span class="st0">`id`</span><span class="br0">&#41;</span> <span class="kw1">ON</span> <span class="kw1">DELETE</span> CASCADE;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> <span class="st0">`categories`</span> <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">`id`</span> int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">`link`</span> varchar<span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">`name`</span> varchar<span class="br0">&#40;</span><span class="nu0">300</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> &nbsp;<span class="br0">&#40;</span><span class="st0">`id`</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span> ENGINE=InnoDB &nbsp;<span class="kw1">DEFAULT</span> CHARSET=utf8 <span class="kw1">AUTO_INCREMENT</span>=<span class="nu0">1</span> ;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> <span class="st0">`users`</span> <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">`id`</span> int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="st0">`name`</span> varchar<span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">`pass`</span> varchar<span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> &nbsp;<span class="br0">&#40;</span><span class="st0">`id`</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span> ENGINE=InnoDB <span class="kw1">DEFAULT</span> CHARSET=utf8 <span class="kw1">AUTO_INCREMENT</span>=<span class="nu0">1</span> ;</div>
</li>
</ol>
</div>
<p>Самый интересный момент здесь касается таблицы <code>bugs</code>, а точнее её поля <code>replyto</code>. Оно даёт возможность отличить комментарий к багу от самого бага. Если значение в нём не равно <code>NULL</code>, то это комментарий, если равно – баг. При этом число, записанное в поле <code>replyto</code>, указывает, к какому багу относится данный комментарий.</p>
<p>Например, в таблице есть четыре следующий записи:</p>
<table style="border-collapse:collapse; font-size:80%">
<tr>
<td style="border:solid 1px #000000">id</td>
<td style="border:solid 1px #000000">title</td>
<td style="border:solid 1px #000000">&#8230;</td>
<td style="border:solid 1px #000000">replyto</td>
</tr>
<tr>
<td style="border:solid 1px #000000">1</td>
<td style="border:solid 1px #000000">Bug 1</td>
<td style="border:solid 1px #000000">&#8230;</td>
<td style="border:solid 1px #000000">NULL</td>
</tr>
<tr>
<td style="border:solid 1px #000000">2</td>
<td style="border:solid 1px #000000">Comment 1</td>
<td style="border:solid 1px #000000">&#8230;</td>
<td style="border:solid 1px #000000">1</td>
</tr>
<tr>
<td style="border:solid 1px #000000">3</td>
<td style="border:solid 1px #000000">Comment 2</td>
<td style="border:solid 1px #000000">&#8230;</td>
<td style="border:solid 1px #000000">1</td>
</tr>
<tr>
<td style="border:solid 1px #000000">4</td>
<td style="border:solid 1px #000000">Bug 2</td>
<td style="border:solid 1px #000000">&#8230;</td>
<td style="border:solid 1px #000000">NULL</td>
</tr>
</table>
<p>Это означает, что мы имеем <strong>два бага</strong> (записи 1 и 4) и <strong>два комментария</strong> (записи 2 и 3), которые относятся к первому багу.</p>
<p>Кстати, значение поля <code>categoryid</code> для всех комментариев равно <code>NULL</code>.</p>
<p>Тут возникает <strong>проблема</strong>. Что будет с комментариями, если мы удалим баг к которому они относятся? Можно, конечно, решить эту проблему так:</p>
<p>1) найти все комментарии, которые относятся к данному багу;<br />
2) удалить их;<br />
3) удалить сам баг.</p>
<p>Но будет лучше, если движок <strong>MySQL</strong> автоматически удалит все связанные комментарии при удалении бага.</p>
<p>Для этого мы объявляем поле <code>replyto</code> внешним ключом (т.е. связываем его с полем <code>id</code>) и указываем опцию <code>ON DELETE CASCADE</code> (каскадное удаление) (строки 13-15). Теперь при удалении записи у которой поле <code>id = 3</code> движок БД будет искать в этой же таблице все записи у которых <code>replyto = 3</code> и удалять их.</p>
<p>И, кроме того, это поле (<code>replyto</code>) мы будем использовать при выводе сообщений о багах на страницах нашего баг трекера.</p>
<p>Но об этом в следующий раз.</p>
<p><strong>До встречи!</strong></p>
<p><strong>Интересно почитать</strong>:<br />
<a title="Слушать радио онлайн" href="http://radiopotok.ru/">Слушать радио онлайн</a></p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=776&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/bug-tracker-ustanovka-frejmvorka-i-sozdanie-bazy-dannyx-chast-vtoraya.html/feed</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Как обойти запрет на XSS</title>
		<link>http://www.simplecoding.org/kak-obojti-zapret-na-xss.html</link>
		<comments>http://www.simplecoding.org/kak-obojti-zapret-na-xss.html#comments</comments>
		<pubDate>Fri, 13 Feb 2009 17:53:42 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[htaccess]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=759</guid>
		<description><![CDATA[Думаю, ни для кого не секрет, что разработчики браузеров стараются сделать серфинг в интернете максимально безопасным. Цель, конечно, прекрасная, но достигается она обычно за счет введения различного рода ограничений, которые усложняют жизнь не только мошенникам.
Приведу небольшой пример. Недавно я рассказывал об использовании Яндекс.Карт и сервиса IPLoc. 
Для получения данных от IPLoc пришлось использовать PHP, хотя, [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_760" class="wp-caption alignnone" style="width: 269px"><img src="http://www.simplecoding.org/wp-content/uploads/2009/02/apache_proxy.png" alt="apache mod_proxy" title="apache mod_proxy" width="259" height="168" class="size-full wp-image-760" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>Думаю, ни для кого не секрет, что разработчики браузеров стараются сделать серфинг в интернете максимально <strong>безопасным</strong>. Цель, конечно, прекрасная, но достигается она обычно за счет введения различного рода <strong>ограничений</strong>, которые усложняют жизнь не только мошенникам.</p>
<p>Приведу небольшой пример. Недавно я рассказывал об <a href="http://www.simplecoding.org/otmechaem-posetitela-na-yandex-karte.html">использовании Яндекс.Карт и сервиса IPLoc</a>. </p>
<p>Для получения данных от <strong>IPLoc</strong> пришлось использовать <strong><acronym title="PHP: Hypertext Preprocessor">PHP</acronym></strong>, хотя, как совершенно справедливо заметил <strong>Big_Shark</strong>, было бы гораздо удобнее отправить этот запрос с помощью <strong>JavaScript</strong>. Но кросс-доменный JavaScript <strong>запрещен</strong> политиками безопасности браузеров.</p>
<p>Тем не менее, мне стало интересно, можно ли обойти это ограничения без использования серверных скриптов (<acronym title="PHP: Hypertext Preprocessor">PHP</acronym>). И решение, конечно, нашлось <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Правда, оно имеет свои недостатки, но об этом чуть ниже.<br />
<span id="more-759"></span><br />
<em>Примечание</em>. По каким-то причинам сервис <a href="http://iploc.mwudka.com/">IPLoc</a> на момент написания этой статьи недоступен. Но есть альтернативные варианты – например, <a href="http://www.wipmania.com/">WIPmania.com</a> (), который имеет очень похожий <acronym title="Application Programming Interface">API</acronym>.</p>
<p>Для начала рассмотрим, как происходит обработка запроса и формирование страницы с использованием <acronym title="PHP: Hypertext Preprocessor">PHP</acronym>.</p>
<div id="attachment_761" class="wp-caption alignnone" style="width: 410px"><img src="http://www.simplecoding.org/wp-content/uploads/2009/02/xss_php.jpg" alt="xss_php" title="xss_php" width="400" height="175" class="size-full wp-image-761" /><p class="wp-caption-text"> </p></div>
<p>Как видите, серверный скрипт должен отправить запрос сервису <strong>WIPmania</strong>, получить от него ответ, сформировать страницу и вернуть её браузеру.</p>
<p>Гораздо интереснее было бы отправить <strong><acronym title="Asynchronous JavaScript and XML">AJAX</acronym> запрос</strong> сервису WIPmania и показать его ответ на странице. При этом необходимость в использовании <strong><acronym title="PHP: Hypertext Preprocessor">PHP</acronym></strong> отпала бы.</p>
<p>Но, как я уже говорил, <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> запрос может быть отправлен только тому серверу, с которого был загружен скрипт. Т.к. изменить поведение браузера мы не можем, то нужно, чтобы наш сервер перенаправил запрос на нужный ресурс (в данном примере WIPmania).</p>
<p>Если в качестве web сервера используется Apache, то для решения этой задачи можно использовать <a href="http://httpd.apache.org/docs/2.0/mod/mod_proxy.html">mod_proxy</a>.</p>
<p>Из названия можно догадаться, что этот модуль <strong>позволяет использовать Apache в качестве прокси сервера</strong>.</p>
<p>Сразу хочу обратить ваше внимание на возможную угрозу безопасности. Нужно максимально ограничить возможность использования прокси. Например, в данном случае, можно разрешить доступ через него только к одному сайту – WIPmania.</p>
<p>На следующей диаграмме показан порядок обработки запросов в этом случае.</p>
<div id="attachment_762" class="wp-caption alignnone" style="width: 460px"><img src="http://www.simplecoding.org/wp-content/uploads/2009/02/xss_mod_proxy.png" alt="xss_mod_proxy" title="xss_mod_proxy" width="450" height="254" class="size-full wp-image-762" /><p class="wp-caption-text"> </p></div>
<p>Как видите, в этом случае <strong>ajax запрос отправляется браузером web серверу</strong>, который получает необходимые данные от WIPmania.</p>
<p>Теперь посмотрим как это реализовать.</p>
<p>1) <strong>Включаем mod_proxy</strong>. Для этого в конфиге apache (httpd.conf) удаляем комментарии перед строками.</p>
<p><code>LoadModule proxy_module modules/mod_proxy.so<br />
LoadModule proxy_http_module modules/mod_proxy_http.so</code></p>
<p>2) Сразу же <strong>запрещаем использовать apache в качестве обычного прокси сервера</strong> (forward proxy).</p>
<p><code>ProxyRequests Off</code></p>
<p>Вообще-то эта опция включена по-умолчанию, но перестраховка не повредит.</p>
<p>3) <strong>Указываем куда нужно отправить запрос</strong>. Допустим, нам нужно, чтобы в ответ на все запросы вида <code>http://simplecoding.org/wipmania...</code> сервер возвращал соответствующий ответ от сервиса WIPmania.</p>
<p>Создаем в корне сайта файл .htaccess со следующим содержимым.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&lt;IfModule mod_rewrite.c&gt;</div>
</li>
<li class="li1">
<div class="de1">RewriteEngine On</div>
</li>
<li class="li1">
<div class="de1">RewriteBase /</div>
</li>
<li class="li1">
<div class="de1">RewriteRule ^wipmania<span class="br0">&#40;</span>.*<span class="br0">&#41;</span> http://api.wipmania.com/$<span class="nu0">1</span> <span class="re0"><span class="br0">&#91;</span>P<span class="br0">&#93;</span></span></div>
</li>
<li class="li2">
<div class="de2">&lt;/IfModule&gt;</div>
</li>
</ol>
</div>
<p>Наибольший интерес здесь представляет 4-ая строка. Во всех запросах, в которых после адреса блога идет слово wipmania, мы первую часть заменяем на <code>http://api.wipmania.com/</code>. Оставшуюся часть запроса оставляем без изменений (нужно для <a href="http://www.wipmania.com/ru/api/">передачи параметров</a>).</p>
<p>Сформированный запрос отправляется через прокси (флаг <code>[P]</code>) серверу api.wipmania.com.</p>
<p>Таким образом мы можем получить данные от любого внешнего сервера. Для браузера эти запросы ничем не отличаются от обычных. Ведь на стороне клиента фактически невозможно установить каким образом web сервер сформировал ответ: прочитал обычный файл, выполнил <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> скрипт или получил данные с другого ресурса.</p>
<p>Так что этот метод будет 100% работать не зависимо от версии браузера и его настроек безопасности (вариант с запретом доступа в интернет вообще я не рассматриваю).</p>
<p>Теперь <strong>о недостатках</strong>.</p>
<p>Главный минус – нужен доступ к конфигу апача. Т.е. shared хостинг отпадает.</p>
<p>К тому же возрастает нагрузка на сервер, т.к. все запросы идут через него.</p>
<p>И, конечно, скорость загрузки данных будет зависеть от скорости сервиса с которым вы работаете. Например, тот же IPLoc сейчас просто недоступен (надеюсь, это временно).</p>
<p>Но есть и <strong>положительный момент</strong>.</p>
<p>Если вы можете реализовать весь функционал с помощью сторонних сервисов и JavaScript, то вам не нужна поддержка <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> (или другого языка).</p>
<p>Как видите, обойти запрет на XSS совсем не сложно <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Если у вас возникли вопросы, пишите, постараюсь ответить.</p>
<p><strong>Небольшое объявление</strong>.</p>
<p><strong>HighLoad-проекту требуется Senior <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> Developer</strong></p>
<p>На проект <a href="http://fotostrana.ru/">fotostrana.ru</a> требуется сильный <acronym title="PHP: Hypertext Preprocessor">PHP</acronym>-разработчик:</p>
<p>    * Опыт веб-разработки от трех лет;<br />
    * Профессиональное владение web-технологиями: <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> 5.0 + MySQL 5.0 + <acronym title="JavaScript">JS</acronym> + <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> и инструментами;<br />
    * Опыт работы с высоконагрузочными (highload) проектами;<br />
    * Участие в создании посещаемых проектов;<br />
    * Умение работать самостоятельно, быстро и на результат;<br />
    * Владение Zend Framework.</p>
<p>Работа в г.Санкт-Петербург. Подробнее на <a href="http://job.fotostrana.ru/">http://job.fotostrana.ru</a></p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=759&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/kak-obojti-zapret-na-xss.html/feed</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Закрываем доступ к сайту с помощью .htaccess и PHP</title>
		<link>http://www.simplecoding.org/zakryvaem-dostup-k-sajtu-s-pomoshhyu-htaccess-i-php.html</link>
		<comments>http://www.simplecoding.org/zakryvaem-dostup-k-sajtu-s-pomoshhyu-htaccess-i-php.html#comments</comments>
		<pubDate>Sun, 18 Jan 2009 14:38:15 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[htaccess]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=725</guid>
		<description><![CDATA[В этой статье я хочу исправить одну из моих ошибок, точнее не совсем ошибку, просто не очень удачный совет.
Дело в том, что недавно я просматривал собственные посты и заметил, что в одном из них задача решается далеко не лучшим образом. Речь шла о блокировке доступа к блогу на движке WordPress.
Решение, которое я тогда предложил, работоспособное [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_726" class="wp-caption alignnone" style="width: 330px"><img src="http://www.simplecoding.org/wp-content/uploads/2009/01/deny_access.png" alt="deny access" title="deny access" width="320" height="116" style="float:left" class="size-full wp-image-726" /><p class="wp-caption-text"> </p></div>
<p>В этой статье я хочу исправить одну из моих ошибок, точнее не совсем ошибку, просто <strong>не очень удачный совет</strong>.</p>
<p>Дело в том, что недавно я просматривал собственные посты и заметил, что в <a href="http://www.simplecoding.org/kak-zakryt-dostup-k-sajtu-na-vremya-obsluzhivaniya.html">одном из них</a> задача решается далеко не лучшим образом. <strong>Речь шла о блокировке доступа к блогу на движке WordPress</strong>.</p>
<p>Решение, которое я тогда предложил, работоспособное и им вполне можно пользоваться. Но только какое-то оно сложное <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Нужно было использовать несколько файлов <strong>.htaccess</strong> для разных папок блога. Доступ для администратора получался немного ограниченным, например, статические ссылки не работали.</p>
<p>И, самое главное. Как абсолютно верно заметил <a href="http://lobach.info/">Олег Лобач</a> в комментариях к тому посту, если сайт закрыт на обслуживание, то необходимо отправлять заголовок с <strong>503</strong> кодом (<strong>Service Unavailable</strong>).</p>
<p>Для посетителей этот код роли не играет, они все равно увидят страницу с описанием ошибки, но вот поисковые боты – другое дело. Думаю, никому не захочется, чтобы в индекс поисковика попала фраза «Зайдите позже» вместо контента блога.</p>
<p>В общем, сейчас хочу рассказать о другом, на мой взгляд, <strong>более удачном решении</strong>.<br />
<span id="more-725"></span><br />
Нужно будет выполнить всего два шага.</p>
<p>1) <strong>Создать страницу</strong>, которую будем показывать посетителям во время обслуживания сайта.</p>
<p>2) <strong>Добавить пару строк в файл .htaccess</strong>, который находится в корне блога.</p>
<p>Кстати, этот метод подойдет практически для любого сайта не зависимо от используемого движка.</p>
<p>Идея заключается в <strong>ограничении доступа на основании <acronym title="Internet Protocol">IP</acronym> адреса</strong>. Т.е. при попытке доступа к сайту web сервер (apache) проверит ваш <acronym title="Internet Protocol">IP</acronym> и если он не совпадет с заданным, то все запросы будут перенаправлены на специальную страницу.</p>
<p>Итак, приступим.</p>
<p><strong>Шаг 1. Создаем страницу с сообщением о том, что сайт временно закрыт</strong>.</p>
<p>Назовем её <strong>maintain.php</strong> и разместим в корне сайта.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">header</span><span class="br0">&#40;</span><span class="st0">&#039;<acronym title="HyperText Transfer Protocol">HTTP</acronym>/1.0 503 Service Unavailable&#039;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">header</span><span class="br0">&#40;</span><span class="st0">&#039;Retry-After: 3600&#039;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">?&gt;</span></div>
</li>
<li class="li2">
<div class="de2">&lt;!DOCTYPE html <span class="kw2">PUBLIC</span> <span class="st0">&quot;-//<acronym title="World Wide Web Consortium">W3C</acronym>//<acronym title="Document Type Definition">DTD</acronym> <acronym title="eXtensible HyperText Markup Language">XHTML</acronym> 1.0 Strict//EN&quot;</span> <span class="st0">&quot;http://www.w3.org/TR/xhtml1/<acronym title="Document Type Definition">DTD</acronym>/xhtml1-strict.dtd&quot;</span>&gt;</div>
</li>
<li class="li1">
<div class="de1">&lt;html xmlns=<span class="st0">&quot;http://www.w3.org/1999/xhtml&quot;</span>&gt;</div>
</li>
<li class="li1">
<div class="de1">&lt;head&gt;</div>
</li>
<li class="li1">
<div class="de1">&lt;meta http-equiv=<span class="st0">&quot;Content-Type&quot;</span> content=<span class="st0">&quot;text/html; charset=UTF-8&quot;</span> /&gt;</div>
</li>
<li class="li1">
<div class="de1">&lt;title&gt;Обслуживание сайта&lt;/title&gt;</div>
</li>
<li class="li2">
<div class="de2">&lt;/head&gt;</div>
</li>
<li class="li1">
<div class="de1">&lt;body&gt;</div>
</li>
<li class="li1">
<div class="de1">&lt;h1&gt;Извините, в данный момент сайт закрыт на обслуживание&lt;/h1&gt;</div>
</li>
<li class="li1">
<div class="de1">&lt;p&gt;Зайдите немного позже&lt;/p&gt;</div>
</li>
<li class="li1">
<div class="de1">&lt;/body&gt;</div>
</li>
<li class="li2">
<div class="de2">&lt;/html&gt;</div>
</li>
</ol>
</div>
<p>Обсуждать тут особенно нечего. Саму страницу, конечно, лучше оформить в соответствии с общим дизайном сайта.</p>
<p>Но сейчас важнее <strong>заголовки</strong> (строки 2 и 3). Для их отправки используется стандартная функция <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> &#8211; <code>header</code>. В её первом параметре указываем заголовок.</p>
<p>Первый заголовок отправляет <strong>503 <acronym title="HyperText Transfer Protocol">HTTP</acronym></strong> код, а второй (<strong>Retry-After</strong>) – время, через которое рекомендуется обновить страницу. В данном примере я установил 1 час (3600 сек), но вы можете выбрать любой интервал времени по своему усмотрению.</p>
<p><strong>Шаг 2. Определяем собственный <acronym title="Internet Protocol">IP</acronym></strong>.</p>
<p>Тут ситуация следующая. Если у вас статический <acronym title="Internet Protocol">IP</acronym> адрес, то вы его знаете и определять ничего не надо <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Но большинство интернет провайдеров просит за него дополнительные деньги. И если вы эту услугу не заказывали, то при подключении <acronym title="Internet Protocol">IP</acronym> адрес будет выдаваться вам каждый раз новый (на практике он меняется довольно редко).</p>
<p>Поэтому заходим на <a href="http://www.whatismyip.com/">эту страницу</a> и переписываем свой текущий <acronym title="Internet Protocol">IP</acronym>-шник.</p>
<p><strong>Шаг 3. Делаем резервную копию файла .htaccess</strong>.</p>
<p>Например, с названием <code>.htaccess_main</code>.</p>
<p><strong>Шаг 4. Добавляем проверку <acronym title="Internet Protocol">IP</acronym></strong>.</p>
<p>В качестве примера, рассмотрим <strong>.htaccess</strong>, который часто используется в блогах на WordPress.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&lt;IfModule mod_rewrite.c&gt;</div>
</li>
<li class="li1">
<div class="de1">RewriteEngine On</div>
</li>
<li class="li1">
<div class="de1">RewriteBase /</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">RewriteCond %<span class="br0">&#123;</span>REQUEST_FILENAME<span class="br0">&#125;</span> !-f</div>
</li>
<li class="li1">
<div class="de1">RewriteCond %<span class="br0">&#123;</span>REQUEST_FILENAME<span class="br0">&#125;</span> !-d</div>
</li>
<li class="li1">
<div class="de1">RewriteRule . /index.php <span class="re0"><span class="br0">&#91;</span>L<span class="br0">&#93;</span></span></div>
</li>
<li class="li1">
<div class="de1">&lt;/IfModule&gt;</div>
</li>
</ol>
</div>
<p><em>Примечание</em>. Правила в этом файле подходят для любого движка, в котором запросы обрабатываются скриптом index.php. Например, для сайтов, использующих фреймворк CodeIgniter такой .htaccess тоже вполне подойдет.</p>
<p>Добавляем две дерективы после <code>RewriteBase /</code></p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">RewriteCond %<span class="br0">&#123;</span>REMOTE_ADDR<span class="br0">&#125;</span> !=<span class="nu0">127.0</span><span class="nu0">.0</span><span class="nu0">.2</span></div>
</li>
<li class="li1">
<div class="de1">RewriteRule ^.* maintain.php <span class="re0"><span class="br0">&#91;</span>L<span class="br0">&#93;</span></span></div>
</li>
</ol>
</div>
<p>Т.е. в результате получится.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">&lt;IfModule mod_rewrite.c&gt;</div>
</li>
<li class="li1">
<div class="de1">RewriteEngine On</div>
</li>
<li class="li1">
<div class="de1">RewriteBase /</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">RewriteCond %<span class="br0">&#123;</span>REMOTE_ADDR<span class="br0">&#125;</span> !=<span class="nu0">127.0</span><span class="nu0">.0</span><span class="nu0">.1</span></div>
</li>
<li class="li1">
<div class="de1">RewriteRule ^.* maintain.php <span class="re0"><span class="br0">&#91;</span>L<span class="br0">&#93;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">RewriteCond %<span class="br0">&#123;</span>REQUEST_FILENAME<span class="br0">&#125;</span> !-f</div>
</li>
<li class="li1">
<div class="de1">RewriteCond %<span class="br0">&#123;</span>REQUEST_FILENAME<span class="br0">&#125;</span> !-d</div>
</li>
<li class="li2">
<div class="de2">RewriteRule . /index.php <span class="re0"><span class="br0">&#91;</span>L<span class="br0">&#93;</span></span></div>
</li>
<li class="li1">
<div class="de1">&lt;/IfModule&gt;</div>
</li>
</ol>
</div>
<p>Естественно, вместо 127.0.0.1 нужно указать свой реальный <acronym title="Internet Protocol">IP</acronym> адрес.</p>
<p><strong>Принцип работы</strong> предельно простой. В директиве <code>RewriteCond</code> (строка 5) мы сравниваем <acronym title="Internet Protocol">IP</acronym> адрес посетителя с указанным. И если они не совпадают – отправляем посетителя на <code>maintain.php</code> (строка 6). Буква <code>L</code> в квадратных скобках указывает, что если это правило выполнилось, то обработку запроса нужно прекратить. Т.е. все последующие строки будут проигнорированы.</p>
<p>Если же вы сами заходите на сайт (<acronym title="Internet Protocol">IP</acronym>-шники совпадают), то директива <code>RewriteRule</code> (в строке 6) пропускается и web сервер обрабатывает запрос как обычно.</p>
<p><strong>Шаг 5. Восстанавливаем доступ к сайту</strong>.</p>
<p>Для этого просто восстанавливаем старый .htaccess файл из резервной копии.</p>
<p><strong>Небольшое дополнение</strong>.</p>
<p>Если в процессе работы у вас изменится <acronym title="Internet Protocol">IP</acronym> адрес, то вам нужно повторить шаг 2, создать .htaccess с новым <acronym title="Internet Protocol">IP</acronym> и скопировать его в корень сайта по <strong><acronym title="File Transfer Protocol">FTP</acronym></strong>.</p>
<p><strong>Вот и все!</strong></p>
<p>Все вопросы и замечания оставляйте в комментариях. Буду рад ответить или обсудить <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>До встречи!</p>
<p><strong>Интересно почитать</strong></p>
<p><a href="http://teplover.com.ua">Штукатурка кирпича по пеноблокам</a> &#8211; достаточно сложная операция&#8230; но только не для профессионалов!<br />
Узнать все <a href="http://slando.by">объявления белоруссии</a> вы сможете с помощью нашего сайта.</p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=725&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/zakryvaem-dostup-k-sajtu-s-pomoshhyu-htaccess-i-php.html/feed</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>Радикальный метод защиты новостного блога от спама</title>
		<link>http://www.simplecoding.org/radikalnyj-metod-zashhity-novostnogo-bloga-ot-spama.html</link>
		<comments>http://www.simplecoding.org/radikalnyj-metod-zashhity-novostnogo-bloga-ot-spama.html#comments</comments>
		<pubDate>Sun, 19 Oct 2008 09:46:29 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[htaccess]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=586</guid>
		<description><![CDATA[Представьте ситуацию. Вы ведете новостной блог, публикуете несколько постов в день, постепенно становитесь популярным   . Количество комментариев постоянно растет, только спама появляется все больше&#8230;
Бороться с этим явлением можно разными способами от установки CAPTCHA до использования специальных служб вроде Akismet. Но вы находитесь в менее выгодном положении, чем большинство блоггеров. Постов очень много и [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_587" class="wp-caption alignnone" style="width: 287px"><img src="http://www.simplecoding.org/wp-content/uploads/2008/10/wordpress_close_old_posts.png" alt="wordpress close old posts" title="wordpress close old posts" width="277" height="106" class="size-full wp-image-587" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>Представьте ситуацию. Вы ведете <strong>новостной блог</strong>, публикуете несколько постов в день, постепенно становитесь популярным <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  . Количество комментариев постоянно растет, только спама появляется все больше&#8230;</p>
<p>Бороться с этим явлением можно разными способами от установки CAPTCHA до использования специальных служб вроде Akismet. Но вы находитесь в менее выгодном положении, чем большинство блоггеров. <strong>Постов очень много</strong> и естественно вы не сможете легко вспомнить, о чем шла речь полгода назад.<br />
<span id="more-586"></span><br />
К тому же все чаще появляется <strong>спам, добавленный людьми</strong>. CAPTCHA от него не защищает вообще, Akismet тоже часто ошибается. Да что там Akismet, иногда, читая такой комментарий, сам сомневаешься спам это или нет. Приходится смотреть о чем был пост, а это требует времени.</p>
<p>Но, как правило, новости широко обсуждаются только <strong>в момент их появления</strong>, а потом о них забывают. Точнее они становятся историей <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  .</p>
<p>Именно для таких постов можно применить самый надежный метод защиты от спама – <strong>закрыть комментарии</strong>.</p>
<p>Сделать это можно вручную через админ-панель WordPress, но есть способ проще.</p>
<p>Достаточно установить плагин <a href="http://wordpress.org/extend/plugins/close-old-posts/">Close Old Posts</a>. Он будет автоматически закрывать комментирование для старых постов.</p>
<p>По-умолчанию, это происходит через 14 дней с момента публикации поста. Естественно эту настройку можно изменить.</p>
<p>Для этого нужно открыть единственный файл плагина close-old-posts.php и изменить переменную:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$cop_days_old</span> = <span class="nu0">14</span>;</div>
</li>
</ol>
</div>
<p>В остальном установка ничем не отличается от большинства других плагинов.</p>
<p>1) Распаковываете архив в папку <code>wp-content/plugins</code>.</p>
<p>2) Активируете.</p>
<p>После этого форма комментирования исчезнет во всех постах старше 14 дней.</p>
<p>К сожалению, для блога вроде этого плагин абсолютно не подходит. Многие статьи, особенно те, в которых речь идет о базовых принципах программирования, остаются актуальными практически всегда. Мне до сих пор приходят комментарии к постам, написанным полгода назад. Причем комментарии «белые», т.е. с вопросами, полезными замечаниями, примерами альтернативных решений и т.п.</p>
<p>Даже если взять этот пост. Он вроде бы новостной, но очень сомнительно, что плагин исчезнет через месяц-другой, скорее выйдет его новая версия <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  . А принцип работы сохранится.</p>
<p>В общем, советую тщательно все взвесить, прежде чем использовать такой метод защиты.</p>
<p>До встречи!</p>
<p><strong>Интересно почитать</strong></p>
<p><a href="http://www.intravels.ru/">InTravels- on-line журнал о путешествиях и туризме</a></p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=586&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/radikalnyj-metod-zashhity-novostnogo-bloga-ot-spama.html/feed</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Извлекаем максимум выгоды из 404 ошибки</title>
		<link>http://www.simplecoding.org/izvlekaem-maksimum-vygody-iz-404-oshibki.html</link>
		<comments>http://www.simplecoding.org/izvlekaem-maksimum-vygody-iz-404-oshibki.html#comments</comments>
		<pubDate>Wed, 03 Sep 2008 14:22:52 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[SEO]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[htaccess]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=462</guid>
		<description><![CDATA[О 404 ошибке знает, наверное, каждый web мастер, а о том, что ее нужно использовать с максимальной выгодой для себя – каждый оптимизатор   .
Ситуация следующая. Эта ошибка возникает, если посетитель обращается к несуществующей странице вашего сайта. Как и почему это произошло – вопрос другой. Может быть, вы сами удалили статью, а может, изменили [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_463" class="wp-caption alignnone" style="width: 284px"><img src="http://www.simplecoding.org/wp-content/uploads/2008/09/404_ask_apache.png" alt="404 ask apache" title="404 ask apache" width="274" height="125" class="size-full wp-image-463" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>О <strong>404 ошибке</strong> знает, наверное, каждый web мастер, а о том, что ее нужно использовать с максимальной выгодой для себя – каждый оптимизатор <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  .</p>
<p>Ситуация следующая. Эта ошибка возникает, если посетитель <strong>обращается к несуществующей странице вашего сайта</strong>. Как и почему это произошло – вопрос другой. Может быть, вы сами удалили статью, а может, изменили ссылку на нее, сейчас это не важно.</p>
<p>Вам нужно любой ценой <strong>оставить посетителя на сайте</strong> <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  .</p>
<p><strong>Самое главное</strong> – не показывать посетителю стандартную страницу, которую возвращает web сервер. Она создает впечатление, что сайт не работает вообще.<br />
<span id="more-462"></span><br />
Самый <strong>простой вариант решения проблемы</strong> – отправить его на главную страницу. Для этого в <code>.htaccess</code> создаем правило.</p>
<p><code>ErrorDocument 404 /index.php</code></p>
<p>Вариант не идеальный, но, по крайней мере, посетитель будет знать, что <strong>сайт работает</strong>, увидит навигационную панель, ссылки на какие-нибудь статьи. Если речь идет о блоге, то не помешает раздел «Самое читаемое».</p>
<p><strong>Второй вариант</strong> – создать специальную страницу, красиво ее оформить, и разместить на ней форму поиска и/или ссылки на самые популярные статьи.</p>
<p>Кстати, очень неплохой и распространенный вариант. Например, многие темы для WordPress имеют такие страницы ошибок.</p>
<p>Только тут есть одна <strong>проблема</strong>. В начале таких страниц обычно пишут текст вроде «Извините, но страница, которую вы искали, отсутствует. Попробуйте воспользоваться формой поиска&#8230;». Т.е. посетитель видит сообщение об ошибке, написанное большими буквами, и уходит.</p>
<p>В общем, <strong>этот текст лучше убрать</strong>. Пусть посетитель смотрит на список ваших лучших материалов.</p>
<p><strong>Третий вариант</strong> – попытаться <strong>предоставить посетителю ту информацию, которую он ищет</strong>. Для этого можно воспользоваться сервисом <a href="http://code.google.com/apis/ajaxsearch/">Google <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> Search <acronym title="Application Programming Interface">API</acronym></a>. Он позволяет встроить в вашу страницу результаты поиска Google. Естественно, можно показывать результаты поиска только по вашему сайту.</p>
<p>Для того, чтобы реализовать этот вариант вам нужно зарегистрироваться в сервисах Google и получить <a href="http://code.google.com/apis/ajaxsearch/signup.html">Google Search <acronym title="Application Programming Interface">API</acronym> Key</a>.</p>
<p>Вместе с ключом вы получите <strong>html код демонстрационной страницы</strong>. Впрочем, владельцам блогов на движке WordPress эта страница не нужна, т.к. существует плагин, который сделает все за вас <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  .</p>
<p>Плагин называется <a href="http://www.askapache.com/seo/404-google-wordpress-plugin.html">AskApache Google 404</a>.</p>
<p>Установить и настроить его не сложно. Вам нужно только <strong>ввести ключ и немного изменить тему</strong>. Добавить строку</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span> <span class="kw1">if</span><span class="br0">&#40;</span><span class="kw3">function_exists</span><span class="br0">&#40;</span><span class="st0">&#039;aa_google_404&#039;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>aa_google_404<span class="br0">&#40;</span><span class="br0">&#41;</span>;?&gt;</div>
</li>
</ol>
</div>
<p>в файл <code>404.php</code>.</p>
<p>Теперь самый <strong>главный вопрос</strong>: «Посетитель зашел на несуществующую страницу. Что искать?».</p>
<p>Плагин поступает очень просто. Он берет название страницы и подставляет его в строку поиска. Например, если посетитель обратится к странице <code>sitename/wordpress-404-plugin</code>, то на странице появятся результаты поиска для слов «<code>wordpress</code>», «<code>404</code>», «<code>plugin</code>».</p>
<p>Это очень удобно, если вы <strong>переименовали страницу и изменили ссылку на нее</strong>. Вероятность того, что переименованная страница окажется в выдаче очень высокая. Кроме того, в выдаче окажутся и другие статьи на эту же тему.</p>
<p>Правда для русскоязычных блогов ситуация немного сложнее, т.к. ссылки обычно записываются транслитом. Но, по моим наблюдениям, Google обычно нормально его распознает и предлагает повторить поиск для слова на русском языке.</p>
<p>Если этот плагин вас заинтересовал, заходите на его <a href="http://www.askapache.com/seo/404-google-wordpress-plugin.html">официальный сайт</a>. Там вы найдете &#034;живую&#034; демонстрацию, скриншоты и ссылки на видеоролики с подробными инструкциями.</p>
<p>Как видите, возможностей море. Главное правильно их использовать.</p>
<p>До встречи!</p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=462&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/izvlekaem-maksimum-vygody-iz-404-oshibki.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Увеличиваем скорость загрузки web страниц</title>
		<link>http://www.simplecoding.org/uvelichivaem-skorost-zagruzki-web-stranic.html</link>
		<comments>http://www.simplecoding.org/uvelichivaem-skorost-zagruzki-web-stranic.html#comments</comments>
		<pubDate>Tue, 12 Aug 2008 10:41:16 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[htaccess]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=401</guid>
		<description><![CDATA[Недавно я наткнулся на одну очень интересную тему для WordPress &#8211; WP-Coda. Выглядит просто шикарно! Но дело не в этом.
Эта тема использует довольно много эффектов, реализованных с помощью JavaScript.
Мне стало интересно, во сколько эта красота обходится посетителям, и оказалось, что не так уж и дорого. Всего один js-файл размером 45кБ.
Дело в том, что автор упаковал [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_402" class="wp-caption alignnone" style="width: 210px"><img src="http://www.simplecoding.org/wp-content/uploads/2008/08/js_box.png" alt="javascript box" title="js_box" width="200" height="215" class="size-full wp-image-402" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>Недавно я наткнулся на одну очень интересную <strong>тему для WordPress</strong> &#8211; <a href="http://bustatheme.com/wordpress/wp-coda/"><acronym title="WordPress">WP</acronym>-Coda</a>. Выглядит просто шикарно! Но дело не в этом.</p>
<p>Эта тема использует довольно много эффектов, реализованных с помощью <strong>JavaScript</strong>.</p>
<p>Мне стало интересно, во сколько эта красота обходится посетителям, и оказалось, что не так уж и дорого. Всего один js-файл размером 45кБ.</p>
<p>Дело в том, что автор упаковал <strong>семь</strong> исходных файлов в один и после этого сжал его упаковщиком вроде Packer <a href="http://joliclic.free.fr/php/javascript-packer/en/">JavaScript en <acronym title="PHP: Hypertext Preprocessor">PHP</acronym></a>.</p>
<p>Но первый же эксперимент показал, что это не предел. Если упаковать этот файл в <strong>gzip архив</strong>, то его размер уменьшается до 21кБ. А большинство современных браузеров прекрасно работают с такими архивами.</p>
<p>При этом <strong>нет необходимости</strong> что-либо переделывать в самой теме.<br />
<span id="more-401"></span><br />
Достаточно <strong>создать архив</strong> и положить его в одну папку с исходным файлом.</p>
<p>После этого <strong>в файл .htaccess добавляем правила</strong>:</p>
<pre>&lt;IfModule mod_rewrite.c&gt;
	RewriteEngine On
	AddEncoding gzip .gz
	RewriteCond %{HTTP:Accept-encoding} gzip
	RewriteCond %{HTTP_USER_AGENT} !Safari
	RewriteCond %{REQUEST_FILENAME}.gz -f
	RewriteRule ^(.*)$ $1.gz [QSA,L]
&lt;/IfModule&gt;</pre>
<p>Работают эти правила так.<br />
1)	включаем RewriteEngine;<br />
2)	указываем, что файлы с расширением .gz имеют <acronym title="Multipurpose Internet Mail Extension">MIME</acronym> тип gzip;<br />
3)	<strong>начинаем проверки</strong>:<br />
	3.1) если браузер принимает gzip;<br />
	3.2) если это не Safari (у него вроде есть проблемы с gzip);<br />
	3.3) если существует файл с таким же именем, как и у запрошенного, но с расширением .gz;<br />
4)	если все проверки прошли успешно, то <strong>добавляем к имени файла расширение .gz</strong> и отправляем этот файл браузеру.</p>
<p>Таким образом, если браузер не работает с gzip, то он получит исходный файл, если поддерживает – получит архив.</p>
<p>Посетитель разницы не заметит. Разве что немного увеличится время загрузки страницы.</p>
<p>В качестве примера, взгляните на скриншоты Firebug, сделанные для блога с темой <acronym title="WordPress">WP</acronym>-Coda.</p>
<p>Исходный вариант:</p>
<div id="attachment_403" class="wp-caption alignnone" style="width: 510px"><img src="http://www.simplecoding.org/wp-content/uploads/2008/08/uncompressed.png" alt="uncompressed javascript" title="uncompressed" width="500" height="31" class="size-full wp-image-403" /><p class="wp-caption-text"> </p></div>
<p>После сжатия и установки правил в .htaccess:</p>
<div id="attachment_404" class="wp-caption alignnone" style="width: 510px"><img src="http://www.simplecoding.org/wp-content/uploads/2008/08/compressed.png" alt="compressed javascript" title="compressed" width="500" height="31" class="size-full wp-image-404" /><p class="wp-caption-text"> </p></div>
<p>Кстати, заметьте, <strong>имя файла в обоих случаях одно и тоже</strong>. Изменяется только его размер. Т.е. браузер в обоих случаях считает, что получил файл, указанный в теге <code>script</code> (<code>global.js</code>), а сервер отправляет в первом случае <code>global.js</code>, а во втором &#8211; <code>global.js.gz</code>.</p>
<p>На мой взгляд, такой подход имеет только <strong>один недостаток</strong>. Во время разработки очень не удобно работать с одним большим js файлом, тем более сжатым <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Вручную упаковывать файлы тоже не интересно, поэтому нужно автоматизировать процесс.</p>
<p>Для этих целей я написал небольшой php скрипт.</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="co1">//подключаем библиотеки</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">require_once</span> <span class="st0">&#039;libs/jsmin-1.1.1.php&#039;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* Путь к папке со скриптами (отностильно этого скрипта)</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*/</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">define</span><span class="br0">&#40;</span><span class="st0">&#039;JS_DIR&#039;</span>, <span class="st0">&quot;test_site/js/&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">/**</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* Имя упакованного файла (будет размещен в папке со скриптами)</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*/</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">define</span><span class="br0">&#40;</span><span class="st0">&#039;JS_OUTPUT_FILE&#039;</span>, <span class="st0">&#039;global.js&#039;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//определяем папку в которой находится скрипт</span></div>
</li>
<li class="li2">
<div class="de2"><span class="re0">$scriptDir</span> = <span class="kw3">substr</span><span class="br0">&#40;</span><span class="re0">$_SERVER</span><span class="br0">&#91;</span><span class="st0">&#039;SCRIPT_FILENAME&#039;</span><span class="br0">&#93;</span>, <span class="nu0">0</span>, <span class="kw3">strrpos</span><span class="br0">&#40;</span><span class="re0">$_SERVER</span><span class="br0">&#91;</span><span class="st0">&#039;SCRIPT_FILENAME&#039;</span><span class="br0">&#93;</span>, <span class="st0">&#039;/&#039;</span><span class="br0">&#41;</span> + <span class="nu0">1</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$resStr</span> = <span class="st0">&quot;&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//открываем папку и получаем список файлов с расширением &quot;js&quot;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$dh</span> = <span class="kw3">opendir</span><span class="br0">&#40;</span><span class="re0">$scriptDir</span>.JS_DIR<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span><span class="kw2">false</span> !== <span class="br0">&#40;</span><span class="re0">$file</span> = <span class="kw3">readdir</span><span class="br0">&#40;</span><span class="re0">$dh</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw3">substr</span><span class="br0">&#40;</span><span class="re0">$file</span>, <span class="kw3">strrpos</span><span class="br0">&#40;</span><span class="re0">$file</span>, <span class="st0">&#039;.&#039;</span><span class="br0">&#41;</span> + <span class="nu0">1</span><span class="br0">&#41;</span> == <span class="st0">&quot;js&quot;</span><span class="br0">&#41;</span> &amp;amp;&amp;amp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="re0">$file</span> != JS_OUTPUT_FILE<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$resStr</span> .= <span class="st0">&quot;/*&#8212;&#8212;&#8212;&quot;</span>.<span class="re0">$file</span>.<span class="st0">&quot;&#8212;&#8212;&#8212;*/<span class="es0">\n</span>&quot;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//сжимаем текущий файл</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$resStr</span> .= JSMin::<span class="me2">minify</span><span class="br0">&#40;</span><span class="kw3">file_get_contents</span><span class="br0">&#40;</span><span class="re0">$scriptDir</span>.JS_DIR.<span class="re0">$file</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="st0">&quot;<span class="es0">\n</span><span class="es0">\n</span>&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw3">closedir</span><span class="br0">&#40;</span><span class="re0">$dh</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">//сохраняем сжатые данные в файл</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$fh</span> = <span class="kw3">fopen</span><span class="br0">&#40;</span><span class="re0">$scriptDir</span>.JS_DIR.JS_OUTPUT_FILE, <span class="st0">&#039;w&#039;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">fwrite</span><span class="br0">&#40;</span><span class="re0">$fh</span>, <span class="re0">$resStr</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">fclose</span><span class="br0">&#40;</span><span class="re0">$fh</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Ошибка: не могу открыть файл для записи: &quot;</span>.<span class="re0">$scriptDir</span>.JS_DIR.JS_OUTPUT_FILE;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Скрипты упакованы файл: &quot;</span>.JS_DIR.JS_OUTPUT_FILE.<span class="st0">&quot;&lt;br /&gt;&quot;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">//архивируем данные (используем самую высокую степень сжатия)</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$gzData</span> = <span class="kw3">gzencode</span><span class="br0">&#40;</span><span class="re0">$resStr</span>, <span class="nu0">9</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">//создаем архив</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$fzip</span> = <span class="kw3">fopen</span><span class="br0">&#40;</span><span class="re0">$scriptDir</span>.JS_DIR.JS_OUTPUT_FILE.<span class="st0">&quot;.gz&quot;</span>, <span class="st0">&#039;wb&#039;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">fwrite</span><span class="br0">&#40;</span><span class="re0">$fzip</span>, <span class="re0">$gzData</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">fclose</span><span class="br0">&#40;</span><span class="re0">$fzip</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Ошибка: не могу открыть файл для записи: &quot;</span>.<span class="re0">$scriptDir</span>.JS_DIR.JS_OUTPUT_FILE.<span class="st0">&quot;.gz&quot;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Создан архив: &quot;</span>.JS_DIR.JS_OUTPUT_FILE.<span class="st0">&quot;.gz&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Ошибка: не могу открыть папку со скриптами&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Принцип работы следующий. Вы указываете папку с js файлами (<code>JS_DIR</code>) и имя файла в который будут упакованы все скрипты (<code>JS_OUTPUT_FILE</code>).</p>
<p>Скрипт читает содержимое всех файлов с расширением js из папки и сжимает его.</p>
<p><em>Примечание</em>. Для сжатия используется <acronym title="PHP: Hypertext Preprocessor">PHP</acronym> версия библиотеки <a href="http://code.google.com/p/jsmin-php/">JSMin</a>. Она просто удаляет пробелы и комментарии из исходных файлов.</p>
<p>После этого сжатые скрипты записываются в файл, указанный в <code>JS_OUTPUT_FILE</code>. <strong>Именно этот файл нужно подключать к вашим страницам</strong>.</p>
<p>Следующим этапом php скрипт создает архив (с помощью функции <code>gzencode</code>), который получает имя <code>JS_OUTPUT_FILE.gz</code>.</p>
<p>Для тестирования я взял библиотеку jQuery и написал js-файл с небольшой функцией, которая создавала пару эффектов.</p>
<p>Т.е. в исходном варианте было 2 файла:<br />
<code>jquery-1.2.3.js</code> – 96кБ<br />
<code>script.js</code> – 1кБ</p>
<p>Сжатый вариант:<br />
<code>global.js</code> – 53,1кБ</p>
<p>Архивный вариант:<br />
<code>global.js.gz</code> – 16кБ</p>
<p>Как видите, разница довольно ощутимая.</p>
<p>Если есть желание поэкспериментировать, <strong>качайте</strong> <a href='http://www.simplecoding.org/wp-content/uploads/2008/08/compress.zip'> архив с скриптом и библиотекой JSMin</a>.</p>
<p>До встречи!</p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=401&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/uvelichivaem-skorost-zagruzki-web-stranic.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Как запретить просмотр содержимого папки на сервере</title>
		<link>http://www.simplecoding.org/kak-zapretit-prosmotr-soderzhimogo-papki-na-servere.html</link>
		<comments>http://www.simplecoding.org/kak-zapretit-prosmotr-soderzhimogo-papki-na-servere.html#comments</comments>
		<pubDate>Thu, 07 Aug 2008 08:36:26 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[Безопасность]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=385</guid>
		<description><![CDATA[
Веб сервер Apache имеет несколько директив (находятся в файле httpd.conf), которые определяют, что будет показано, когда посетитель заходит в какую-то папку.
Прежде всего, это
DirectoryIndex
Она определяет, какой файл будет отправлен посетителю, если он не указал его имя явно. В параметрах этой директивы перечисляются имена файлов. Например:

DirectoryIndex index.php index.html index.htm
Приоритет имеет тот файл, который идет первым в списке. [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-384" style="float:left" title="brouser_htaccess" src="http://www.simplecoding.org/wp-content/uploads/2008/08/brouser_htaccess.jpg" alt="Логотип для htaccess" width="400" height="282" /></p>
<p>Веб сервер <strong>Apache</strong> имеет несколько директив (находятся в файле <code>httpd.conf</code>), которые определяют, что будет показано, когда посетитель заходит в какую-то папку.</p>
<p>Прежде всего, это<br />
<code>DirectoryIndex</code></p>
<p>Она определяет, какой файл будет отправлен посетителю, если он <strong>не указал его имя явно</strong>. В параметрах этой директивы перечисляются имена файлов. Например:<br />
<span id="more-385"></span><br />
<code>DirectoryIndex index.php index.html index.htm</code></p>
<p>Приоритет имеет тот файл, который идет первым в списке. Т.е. если папка содержит index.php и index.html, то посетителю будет отправлен index.php.</p>
<p>Теперь небольшой пример. Допустим, сайт имеет такую структуру.<br />
<code> </code></p>
<pre>/
index.html
page1.html
page2.html
css/
    styles.css</pre>
<p>По адресу <code>http://sitename/</code> вы увидите страницу <code>index.html</code>.<br />
Но если зайти в папку <code>css</code> (<code>http://sitename/css</code>), то картинка будет примерно такая</p>
<div id="attachment_386" class="wp-caption alignnone" style="width: 401px"><img class="size-full wp-image-386" title="files_list" src="http://www.simplecoding.org/wp-content/uploads/2008/08/files_list.png" alt="Список файлов на сервере" width="391" height="124" /><p class="wp-caption-text">Список файлов на сервере</p></div>
<p>Т.е. сервер покажет вам <strong>список файлов</strong> в этой папке. Не думаю, что кому-то понравится такое поведение сервера.</p>
<p>Исправить ситуацию можно с помощью директивы:</p>
<p><code>Options -Indexes</code></p>
<p>Примечание: символ «<code>-</code>» перед словом Indexes означает, что индексирование содержимого папок запрещено.</p>
<p>Теперь если вы попытаетесь зайти в папку css, то увидите сообщение:</p>
<p><strong>Forbidden</strong><br />
You don&#039;t have permission to access /css/ on this server. (у вас нет прав для доступа к /css/ на этом сервере).</p>
<p>При этом доступ к файлу styles.css (<code>http://sitename/css/styles.css</code>) сохраняется.</p>
<p>Если вы не можете конфигурировать Apache (например, сайт находится на shared хостинге), то создайте в корне сайта файл <code>.htaccess</code> с этой директивой.</p>
<p>В этом случае индексирование будет запрещено не только для корневой папки, но и для всех вложенных папок (если, конечно, они не содержат своих файлов <code>.htaccess</code>).</p>
<p>Правда, этот <strong>метод может не работать</strong>. Дело в том, что обработка файлов <code>.htaccess</code> может быть запрещена директивой <code>AllowOverride</code> none (в файле httpd.conf).</p>
<p>В этом случае вам нужен либо доступ к httpd.conf, либо придется в каждой папке размещать файлы <code>index.html</code> с каким-нибудь текстом (что-то вроде Access forbidden). Кстати, разработчики фреймворка CodeIgniter именно так и поступают (в каждой вложенной в system папке находится <code>index.html</code>).</p>
<p><em>Примечание</em>. Для того чтобы вступили в силу изменения в <code>httpd.conf</code> нужно перезапустить сервер. Изменения в <code>.htaccess</code> начнут работать сразу после сохранения файла.</p>
<p><strong>Спонсор статьи</strong>:<br />
<a href="http://www.blog-codera.net/"> Записки webмастера. Читать всем! </a></p><img src="http://www.simplecoding.org/?ak_action=api_record_view&id=385&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/kak-zapretit-prosmotr-soderzhimogo-papki-na-servere.html/feed</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
	</channel>
</rss>
