<?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>Программирование и вебдизайн &#187; кодировка</title>
	<atom:link href="http://rucode.infonex.us/category/kodirovka/feed/" rel="self" type="application/rss+xml" />
	<link>http://rucode.infonex.us</link>
	<description>Just another Informational Blog weblog</description>
	<lastBuildDate>Sat, 18 Feb 2012 12:37:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>PHP и UTF-8</title>
		<link>http://rucode.infonex.us/2010/03/07/php-i-utf-8/</link>
		<comments>http://rucode.infonex.us/2010/03/07/php-i-utf-8/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 12:44:32 +0000</pubDate>
		<dc:creator>Dmitriy Lyapin</dc:creator>
				<category><![CDATA[BOM]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[UTF-8]]></category>
		<category><![CDATA[кодировка]]></category>
		<category><![CDATA[Программирование]]></category>

		<guid isPermaLink="false">http://svitter.ru/?p=915</guid>
		<description><![CDATA[Хорошим тоном считается использовать кодировку UTF-8, несмотря на то, что большинство сайтов рунета до сих пор работают на Windows-1251. В статье я расскажу, что же именно нужно сделать, чтобы PHP сайт правильно заработал с Юникодом, и с каким трудностями мне пришлось столкнуться на пути к прогрессу.

Достаточно ли тега meta?
Вот мой index.php:

&#60;!DOCTYPE html PUBLIC &#34;-//W3C//DTD HTML [...]]]></description>
			<content:encoded><![CDATA[<p>Хорошим тоном считается использовать кодировку UTF-8, несмотря на то, что большинство сайтов рунета до сих пор работают на Windows-1251. В статье я расскажу, что же именно нужно сделать, чтобы PHP сайт правильно заработал с Юникодом, и с каким трудностями мне пришлось столкнуться на пути к прогрессу.</p>
<p><span id="more-915"></span></p>
<h3>Достаточно ли тега meta?</h3>
<p>Вот мой index.php:</p>
<div class="wp_syntax">
<div class="code">
<pre class="html4strict" style="font-family:monospace;"><span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">meta</span> <span style="color: #000066;">http-equiv</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;content-type&quot;</span> <span style="color: #000066;">content</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/html; charset=utf-8&quot;</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>UTF-8<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
	Здравствуй, UTF-8!
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span></pre>
</div>
</div>
<p></html></p>
<p>Сохраняю файл в кодировке UTF-8 и вижу в браузере каркозябры. Это меня не может не удивлять, потому что в теге meta указана верная кодировка.</p>
<p>Несмотря на это, все браузеры упорно считают, что документ пришел в Windows-1251.</p>
<p><img src="http://svitter.ru/wp-content/uploads/2010/03/utf8.jpg" alt="utf8" title="utf8" width="743" height="291" class="alignnone size-full wp-image-916" /></p>
<p>Почему?</p>
<h3>Статичная страница вместо скрипта</h3>
<p>Пробую поменять расширение файла на &laquo;.html&raquo; и, о чудо! Я вижу надпись &laquo;Здравствуй, UTF-8!&raquo; Значит, дело в PHP&#8230;</p>
<h3>Заголовки ответа</h3>
<p>А не отправляет ли сервер кодировку в заголовке ответа? Запускаю мониторинг HTTP (<a href="http://svitter.ru/?p=772">как это сделать?</a>) и вижу вот что:</p>
<div class="wp_syntax">
<div class="code">
<pre class="text" style="font-family:monospace;">Content-type: text/html; charset=windows-1251</pre>
</div>
</div>
<p>То есть сервер считает, что страница должна быть в кодировке Windows-1251, о чем говорит браузеру заголовком Content-type.</p>
<h3>Решение проблемы</h3>
<p>Решить проблему можно двумя способами:</p>
<ol>
<li>
Написать в начале скрипта (перед выводом HTML):</p>
<div class="wp_syntax">
<div class="code">
<pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-type: text/html; charset=utf-8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre>
</div>
</div>
</li>
<li>
Указать в .htaccess нужную кодировку:</p>
<div class="wp_syntax">
<div class="code">
<pre class="text" style="font-family:monospace;">AddDefaultCharset utf-8</pre>
</div>
</div>
</li>
</ol>
<p>Оба варианта приведут к одному и тому же &#8211; сервер вернет нужный нам заголовок:</p>
<div class="wp_syntax">
<div class="code">
<pre class="text" style="font-family:monospace;">Content-type: text/html; charset=utf-8</pre>
</div>
</div>
<h3>Для чего же тогда тег meta?</h3>
<p>Для статичных страничек или же, если пользователь сохранит документ для автономной работы.</p>
<h3>Метка BOM</h3>
<p>Работая в кодировке UTF-8, нужно знать про злую метку <a href="http://en.wikipedia.org/wiki/Byte_order_mark">BOM</a>. Это такая последовательность байт, которая идет в начале файла и &laquo;помогает&raquo; понять кодировку. Однако для PHP эта метка оказывает медвежью услугу. Последовательность байт просто выводится в OUTPUT, в результате чего возникают разные неприятные вещи.</p>
<p>Например, IE отказывается реагировать на директиву DOCTYPE (видимо, он ее ждет в самом начале файла, а там BOM). Если вы используете шаблоны, и для вывода HTML используется несколько файлов, то браузер будет отображать отступы в местах стыка шаблонов.</p>
<p>Решение проблемы &#8211; использовать UTF-8 без BOM. Многие редакторы позволяют это делать, например, Notepad++:</p>
<p><img src="http://svitter.ru/wp-content/uploads/2010/03/bom.jpg" alt="bom" title="bom" width="472" height="231" class="alignnone size-full wp-image-917" /></p>
<p><img src="http://feeds.feedburner.com/~r/svitter/articles/~4/dpMeWmp_8Qg" height="1" width="1"/></p>
<div id="crp_related"><h4>Related Posts:</h4><ul><li><a href="http://rucode.infonex.us/2010/04/05/kodikevich-i-vyichislitelnyiy-klaster/" rel="bookmark" class="crp_title">Кодикевич и вычислительный кластер</a></li><li><a href="http://rucode.infonex.us/2010/03/19/rasputyivanie-zlogo-koda/" rel="bookmark" class="crp_title">Распутывание злого кода</a></li><li><a href="http://rucode.infonex.us/2010/04/09/russkiy-yazyik-vyibor-okonchaniy/" rel="bookmark" class="crp_title">Русский Язык. Выбор окончаний</a></li><li><a href="http://rucode.infonex.us/2010/04/01/zloy-plagin-dlya-jquery/" rel="bookmark" class="crp_title">Злой плагин для jQuery</a></li><li><a href="http://rucode.infonex.us/2010/03/09/avtomatizatsiya-podpiski-na-rassyilku-feedburner-chast-3/" rel="bookmark" class="crp_title">Автоматизация подписки на рассылку FeedBurner. Часть 3</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://rucode.infonex.us/2010/03/07/php-i-utf-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Работа с форматом ZIP в C#</title>
		<link>http://rucode.infonex.us/2010/02/25/rabota-s-formatom-zip-v-c/</link>
		<comments>http://rucode.infonex.us/2010/02/25/rabota-s-formatom-zip-v-c/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 14:57:36 +0000</pubDate>
		<dc:creator>Dmitriy Lyapin</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[SharpZipLib]]></category>
		<category><![CDATA[zip]]></category>
		<category><![CDATA[кодировка]]></category>
		<category><![CDATA[Программирование]]></category>

		<guid isPermaLink="false">http://svitter.ru/?p=898</guid>
		<description><![CDATA[
Для упаковки и распаковки ZIP архивов средствами Net Framework существует множество библиотек. Одна из наиболее популярных &#8211; ICSharpCode.SharpZipLib. Распространяется библиотека по лицензии GPL и в целом производит приятное впечатление.
Она позволяет работать с форматом ZIP на относительно низком уровне, исползуя классы ZipInputStream, ZipOutputStream, ZipEntry и др. А можно ограничиться функциями &#171;запаковать директорию в архивчик&#187; и &#171;распаковать [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://svitter.ru/wp-content/uploads/2010/02/icsharpcode.jpg" alt="icsharpcode" width="137" height="56" class="alignright size-full wp-image-899" /></p>
<p>Для упаковки и распаковки ZIP архивов средствами Net Framework существует множество библиотек. Одна из наиболее популярных &#8211; <a href="http://www.icsharpcode.net/OpenSource/SharpZipLib/">ICSharpCode.SharpZipLib</a>. Распространяется библиотека по лицензии GPL и в целом производит приятное впечатление.</p>
<p>Она позволяет работать с форматом ZIP на относительно низком уровне, исползуя классы <em>ZipInputStream</em>, <em>ZipOutputStream</em>, <em>ZipEntry</em> и др. А можно ограничиться функциями &laquo;запаковать директорию в архивчик&raquo; и &laquo;распаковать архивчик в директорию&raquo;, это умеет класс <em>FastZip</em>.</p>
<p>Все настолько просто, что если бы у меня не возникло загадочных проблем с кириллицей в именах файлов, то не было бы и этой статьи про <strong>ZIP</strong> и <strong>C#</strong>.</p>
<p><span id="more-898"></span></p>
<p>В веб-приложении (ASP.NET) по некой команде пользователя нужно запаковывать два файла в архив и отдавать его на скачивание. Для этого создается временная директория, туда помещаются файлы, далее они пакуются в архив.</p>
<div class="wp_syntax">
<div class="code">
<pre class="csharp" style="font-family:monospace;">tempDir <span style="color: #008000;">=</span> Path.<span style="color: #0000FF;">GetTempPath</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">+</span> Guid.<span style="color: #0000FF;">NewGuid</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">+</span> <span style="color: #666666;">&quot;<span style="color: #008080; font-weight: bold;">\\</span>&quot;</span><span style="color: #008000;">;</span>
Directory.<span style="color: #0000FF;">CreateDirectory</span><span style="color: #000000;">&#40;</span>tempDir<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
...
&nbsp;
<span style="color: #0000FF;">FastZip</span> fz <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> FastZip<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
fz.<span style="color: #0000FF;">CreateZip</span><span style="color: #000000;">&#40;</span>filename, tempDir, <span style="color: #0600FF;">true</span>, <span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre>
</div>
</div>
<p>Этот код прекрасно работал при запуске веб-сервера по F5 в VisualStudio. Однако на реальном сервере FastZip отказывался понимать кириллицу в именах файлов и заменял такие символы на знаки вопроса.</p>
<p>Для выявления проблемы я создал папку (&raquo;D:\test&raquo;) с двумя файлами (&raquo;первый.txt&raquo;, &laquo;второй.txt&raquo;) и поставил задачу заархивировать ее. Вместо веб-сервера было написано конслоьное приложение. Вот его код:</p>
<div class="wp_syntax">
<div class="code">
<pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">void</span> Main<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
	FastZip fz <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> FastZip<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	fz.<span style="color: #0000FF;">CreateZip</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;D:<span style="color: #008080; font-weight: bold;">\\</span>test.zip&quot;</span>, <span style="color: #666666;">&quot;D:<span style="color: #008080; font-weight: bold;">\\</span>test&quot;</span>, <span style="color: #0600FF;">true</span>, <span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre>
</div>
</div>
<p>К моему удивлению, оно отработало на сервере безупречно! Значит, предположение, что проблема кроется в том, что на локальном компьютере у меня русская версия Windows, а на сервере &#8211; американская, было неверным.</p>
<p>Как оказалось, в библиотеке SharpZipLib есть такой класс <em>ZipConstants</em>, а у него есть свойство <em>DefaultCodePage</em>. В консольном приложении ZipConstants.DefaultCodePage = 866 (что хорошо), а на веб-сервере ZipConstants.DefaultCodePage = 437 (что нехорошо).</p>
<p>Решение проблемы оказалось совсем простым. Нужно добавить куда-нибудь перед архивацией эту строчку:</p>
<div class="wp_syntax">
<div class="code">
<pre class="csharp" style="font-family:monospace;">ZipConstants.<span style="color: #0000FF;">DefaultCodePage</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">866</span><span style="color: #008000;">;</span></pre>
</div>
</div>
<p>Передаю приветы:<br />
- Гоше, проблема была в его коде <img src='http://svitter.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
- Пользователю <a href="http://forum.ru-board.com/topic.cgi?forum=33&#038;bm=1&#038;topic=11019#1">volser</a> с форума ru-board; спасибо за <a href="http://community.sharpdevelop.net/forums/p/5287/15152.aspx">ссылку</a>, которая решила мою проблему!</p>
<p><img src="http://feeds.feedburner.com/~r/svitter/articles/~4/DbqGB37jsy0" height="1" width="1"/></p>
<div id="crp_related"><h4>Related Posts:</h4><ul><li><a href="http://rucode.infonex.us/2010/04/05/kodikevich-i-vyichislitelnyiy-klaster/" rel="bookmark" class="crp_title">Кодикевич и вычислительный кластер</a></li><li><a href="http://rucode.infonex.us/2010/04/09/russkiy-yazyik-vyibor-okonchaniy/" rel="bookmark" class="crp_title">Русский Язык. Выбор окончаний</a></li><li><a href="http://rucode.infonex.us/2010/03/26/uchimsya-memorizirovat/" rel="bookmark" class="crp_title">Учимся меморизировать</a></li><li><a href="http://rucode.infonex.us/2010/03/09/avtomatizatsiya-podpiski-na-rassyilku-feedburner-chast-3/" rel="bookmark" class="crp_title">Автоматизация подписки на рассылку FeedBurner. Часть 3</a></li><li><a href="http://rucode.infonex.us/2010/03/19/rasputyivanie-zlogo-koda/" rel="bookmark" class="crp_title">Распутывание злого кода</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://rucode.infonex.us/2010/02/25/rabota-s-formatom-zip-v-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

