Php header charset windows 1251

  1. Доступные статьи

  2. PHP

  3. Локали и кодировки

Локали и кодировки

  1. Введение
  2. Работа с локалями в PHP

    • Windows
    • UNIX (FreeBSD)
  3. Кодировки в MySQL
  4. Кодировка HTML-страниц
  5. Заключение

Введение

При разработке веб-приложений есть три важных момента, связанных с кодировками: информация в файлах-сценариях, информация в базе данных и браузер пользователя. Если выставить хотя бы одну кодировку неверно, то, в лучшем случае, данные отобразятся неверно, в худшем, безвозвратно потеряются. Чтобы этого не произошло, а приложение работало корректно при любых настройках сервера, нужно правильно выставить кодировки.

Работа с локалями в PHP

Работа с локалями в PHP выглядит одинаково и в UNIX, и в Windows, и в любой другой платформе. Для установки значений локали служит всего одна функция setlocale(). Чтобы выставить локаль, нужно передать функции первым аргументом категорию, на которую эта локаль распространяется, последующими список возможных локалей. Результатом будет название первой подходящей локали, которая и была установлена.

Пример - установка и использование локали
<?php 
// Установка локали
echo setlocale(LC_ALL, 'ru_RU.CP1251', 'rus_RUS.CP1251', 'Russian_Russia.1251');

// Выведет ru_RU.CP1251 для FreeBSD
// Выведет rus_RUS.CP1251 для линукса
// Выведет Russian_Russia.1251 для Windows

// ...

// Вывод локализованных сообщений, например, даты
echo '<br />', strftime('Число: %d, месяц: %B, день недели: %A');
?>

ru_RU.CP1251
Число: 10, месяц: октября, день недели: пятница

или

Russian_Russia.1251
Число: 10, месяц: Октябрь, день недели: пятница

Локали в Windows

Для того, чтобы узнать, какие локали доступны в Windows, нужно зайти в панель управления, «Язык и региональные стандарты».

зык и региональные настройки. Список локалей Windows.

На вкладке «Дополнительно», в разделе «Кодовые страницы таблиц преобразования» показан список всех возможных локалей для Windows, которые можно использовать в PHP.

Кодовые страницы, которые отмечены в списке, из PHP могут быть использованы по их номеру.

В общем случае, использование выглядит по следующей схеме: Язык_Регион.Номер_кодовой_страницы

Для России это может выглядеть как Russian_Russia.1251 (cp1251) или Russian_Russia.20866 (KOI8-R).

Для Украины — Ukrainian_Ukraine.1251 (cp1251).

Вместо длинных названий можно использовать сокращённые russian, american, ukrainian и так далее. При этом кодовая страница выставится с учётом региональных настроек, для России и Украины — 1251, для Америки — 1252.

Единственная кодировка, с которой у меня возникли проблемы, как ни странно, оказалась UTF-8. При попытке выставить эту кодировку, выставляются все категории локалей, кроме основной. Вывод локализованных сообщений при этом идёт в cp1251.

Пример - установка локали UTF-8 на Windows
<?
// Кодировка страницы windows-1251
header('Content-Type: text/html; charset=windows-1251');

echo '<pre>';

// Локаль устанавливаем UTF-8
echo setlocale(LC_ALL, 'Russian_Russia.65001'), PHP_EOL;

// Но данные будут выводиться всё равно в cp1251 :(((
echo strftime('%A'), PHP_EOL;

?>
LC_COLLATE=Russian_Russia.65001;LC_CTYPE=Russian_Russia.1251;
LC_MONETARY=Russian_Russia.65001;LC_NUMERIC=Russian_Russia.65001;
LC_TIME=Russian_Russia.65001
пятница

Пока это можно списать на внутренний механизм PHP работы со строками. С шестой версии PHP вся обработка строк должна будет вестись в UTF-8, но до тех пор надо просто знать об этом и делать поправку.

Ещё одной странностью при работе с локалями в PHP на Windows является неправильная работа с категориями локалей. Так, например, я выставляю локаль на функции времени KOI8-R, setlocale(LC_TIME, 'Russian_Russia.20866'), но почему-то выставляется cp1251 на все категории. Суть проблемы я так и не понял, возможно, это просто баг (проверялось на PHP 5.2.3), а возможно, что внутренний механизм Windows просто не позволяет этого делать. Хотя по мне, так это чистой воды баг.

В общем-то, на этом можно и закончить разговор о локалях на Windows. Главное, запомнить, что локали, которые портированы из UNIX, под WIndows работают только для «галочки». Шаг влево, шаг вправо и результат будет непредсказуемым. Безопасно можно использовать только cp1251 (windows-1251) и KOI8-R, и только для LC_ALL.

Код - установка локали на Windows
<?php
// Устновка локалей для Windows

// Кодировка Windows-1251
setlocale(LC_ALL, 'Russian_Russia.1251');

// Кодировка KOI8-R
setlocale(LC_ALL, 'Russian_Russia.20866');

// Кодировка UTF-8 (использовать осторожно)
setlocale(LC_ALL, 'Russian_Russia.65001');

?>

Локали в UNIX

Выше я описал работу с локалями в Windows, теперь можно заострить внимание на UNIX-like системах. Для простоты, я буду их называть UNIX, а подразумевать FreeBSD :). В контексте данной статьи это не особо важно.

Итак, дистрибутивы UNIX поставляются в одном виде для всех, и работа рассчитана на многопользовательский режим, поэтому о правильной настройке локали должен заботиться сам пользователь, например:

zg# locale
LANG=
LC_CTYPE="ru_RU.KOI8-R"
LC_COLLATE="ru_RU.KOI8-R"
LC_TIME="ru_RU.KOI8-R"
LC_NUMERIC="ru_RU.KOI8-R"
LC_MONETARY="ru_RU.KOI8-R"
LC_MESSAGES="ru_RU.KOI8-R"
LC_ALL=ru_RU.KOI8-R
zg#

Так может выглядеть работа системной команды locale, которая выводит текущие настройки локали для пользователя. А так, обычно, выглядят настройки локали для пользователя, под которым работает PHP:

passthru('locale');
================
LANG=
LC_CTYPE="C" 
LC_COLLATE="C" 
LC_TIME="C" 
LC_NUMERIC="C" 
LC_MONETARY="C" 
LC_MESSAGES="C" 
LC_ALL= 

Функция ucwords() должна была сделать заглавными первые буквы всех слов. А перед этим strtolower() должна была предварительно все заглавные буквы сделать строчными. Но ничего не произошло. Так же не будет работать следующий код:

echo ucwords(strtolower('привет, МИР!'));
================
привет, МИР!

Хотя \w является множеством знаков, из которых может состоять слово (алфавит, цифры и _), регулярное выражение не срабатывает. Причина как раз в том, что, работая с cp1251, мы не сказали об этом php. Чтобы исправить положение, достаточно воспользоваться функцией setlocale() и указать правильную локаль, например, так:

setlocale(LC_ALL, 'ru_RU.CP1251');

Здесь первый аргумент — это категория, на которую будет распространяться локаль (константа LC_*), второй — название локали. Начиная с версии 4.3.0 можно указывать несколько имён локалей в виде массива или в качестве дополнительных аргументов. После вызова функция установит первую подходящую локаль и вернёт её имя:

echo setlocale(LC_ALL, 'cp1251', 'koi8-r', 'ru_RU.KOI8-R');
================
ru_RU.KOI8-R

С помощью команды grep я отобрал локали, которые поддерживают русский язык. Любую из них можно использовать, однако следует понимать, что данные должны быть в кодировке, на которую рассчитана локаль. Если же это правило не будет соблюдено, то результат может оказаться весьма неожиданным:

echo setlocale(LC_ALL, 'ru_RU.KOI8-R'), PHP_EOL;
echo ucwords(strtolower('привет, МИР!'));
===============
ru_RU.KOI8-R
пРИВЕТ, мИР!

Если учесть, что koi8-r достаточно популярная кодировка для UNIX-севреров, а windows-1251 для русскоязычных сайтов, то подобное «необычное» поведение не такая уж и редкость. Когда-то я и сам столкнулся с этой проблемой при портировании проекта на реальный хостинг.

После установки правильной локали все примеры, которые не работали выше, будут работать как нужно!

echo setlocale(LC_ALL, 'ru_RU.CP1251', 'rus_RUS.CP1251', 'Russian_Russia.1251'), PHP_EOL;
echo ucwords(strtolower('привет, МИР!')), PHP_EOL;
echo preg_match('/^\w+$/', 'привет') ? 'нашёл' : 'не работает', PHP_EOL;
echo strftime('Сегодня: %A, %d %B, %Y года');
===============
ru_RU.CP1251
Привет, Мир!
нашёл
Сегодня: суббота, 12 июля, 2008 года

По-русски заговорит и функция strftime(), которая корректно работает с локалями, а также и всё остальное, что зависит от локали.

Кодировки в MySQL

Напомню, что возможность задавать кодировки появилась только в MySQL 4.1.11 и выше.

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

Первое, чему необходимо научиться, смотреть текущие настройки соединения с mysql:

mysql> show variables like 'char%';
+--------------------------+----------------------------------+
| Variable_name            | Value                            |
+--------------------------+----------------------------------+
| character_set_client     | cp1251                           |
| character_set_connection | cp1251                           |
| character_set_database   | cp1251                           |
| character_set_filesystem | binary                           |
| character_set_results    | cp1251                           |
| character_set_server     | cp1251                           |
| character_set_system     | utf8                             |
| character_sets_dir       | /usr/local/share/mysql/charsets/ |
+--------------------------+----------------------------------+
8 rows in set (0.00 sec)

Критичными для пользователя являются character_set_client и character_set_results, которые отвечают за кодировку, в которой данные поступают в базу, и кодировку, в которой данные поступают из базы к пользователю. Если эти две кодировки отличаются от той, в которой работает клиент, в нашем случае php-скрипты, то неминуемо будут «странности», например, при сортировке выборки или внесении данных в базу.

Второе, что необходимо знать, как правильно сообщить mysql о кодировках. Самый простой и правильный способ, это использовать запрос set names:

mysql> set names 'cp1251';
Query OK, 0 rows affected (0.00 sec)

После этого три переменные character_set_client, character_set_connection и character_set_results примут значение cp1251. Это будет означать — клиент работает в кодировке windows-1251 (cp1251).

Помимо этого можно устанавливать непосредственно серверные переменные:

mysql> set character_set_client='UTF8';
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'char%';
+--------------------------+----------------------------------+
| Variable_name            | Value                            |
+--------------------------+----------------------------------+
| character_set_client     | utf8                             |
| character_set_connection | cp1251                           |
.....

Теперь данные поступают и извлекаются в разных кодировках.

Список доступных кодировок можно просмотреть так:

mysql> show charset;
+----------+-----------------------------+---------------------+--------+
| Charset  | Description                 | Default collation   | Maxlen |
+----------+-----------------------------+---------------------+--------+
| dec8     | DEC West European           | dec8_swedish_ci     |      1 |
| cp850    | DOS West European           | cp850_general_ci    |      1 |
| hp8      | HP West European            | hp8_english_ci      |      1 |
| koi8r    | KOI8-R Relcom Russian       | koi8r_general_ci    |      1 |
| latin1   | cp1252 West European        | latin1_swedish_ci   |      1 |
| latin2   | ISO 8859-2 Central European | latin2_general_ci   |      1 |
| swe7     | 7bit Swedish                | swe7_swedish_ci     |      1 |
| ascii    | US ASCII                    | ascii_general_ci    |      1 |
| hebrew   | ISO 8859-8 Hebrew           | hebrew_general_ci   |      1 |
| koi8u    | KOI8-U Ukrainian            | koi8u_general_ci    |      1 |
| greek    | ISO 8859-7 Greek            | greek_general_ci    |      1 |
| cp1250   | Windows Central European    | cp1250_general_ci   |      1 |
| latin5   | ISO 8859-9 Turkish          | latin5_turkish_ci   |      1 |
| armscii8 | ARMSCII-8 Armenian          | armscii8_general_ci |      1 |
| utf8     | UTF-8 Unicode               | utf8_general_ci     |      3 |
| cp866    | DOS Russian                 | cp866_general_ci    |      1 |
| keybcs2  | DOS Kamenicky Czech-Slovak  | keybcs2_general_ci  |      1 |
| macce    | Mac Central European        | macce_general_ci    |      1 |
| macroman | Mac West European           | macroman_general_ci |      1 |
| cp852    | DOS Central European        | cp852_general_ci    |      1 |
| latin7   | ISO 8859-13 Baltic          | latin7_general_ci   |      1 |
| cp1251   | Windows Cyrillic            | cp1251_general_ci   |      1 |
| cp1256   | Windows Arabic              | cp1256_general_ci   |      1 |
| cp1257   | Windows Baltic              | cp1257_general_ci   |      1 |
| binary   | Binary pseudo charset       | binary              |      1 |
| geostd8  | GEOSTD8 Georgian            | geostd8_general_ci  |      1 |
+----------+-----------------------------+---------------------+--------+
26 rows in set (0.00 sec)

И третье, что необходимо знать, — правила создания таблиц для хранения данных в нужной кодировке. К слову, данные можно хранить в любой кодировке, а работать с ними в кодировке клиента. Однако, важно понимать, что кодировки носят национальный характер и должны соответствовать вносимым данным. Иначе будут потери. Для русского языка есть три национальных кодировки koi8r, cp866, cp1251, которые могут конвертироваться друг в друга без потерь. Также можно использовать интернациональную кодировку UTF8.

Кодировку можно выставить на базу данных, таблицу и поле таблицы. Так, например, можно создать базу данных в кодировке koi8r:

CREATE DATABASE `test` DEFAULT CHARACTER SET koi8r;

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

Следующим шагом я создам таблицу в cp1251 и одним полем в utf8:

CREATE TABLE `t` (
`id` VARCHAR( 60 ) NOT NULL ,
`data` TEXT CHARACTER SET utf8 NOT NULL ,
PRIMARY KEY ( `id` ) 
) TYPE = MYISAM CHARACTER SET cp1251;

После того, как таблица создана с нужными параметрами кодировки, mysql автоматически начинает переводить данные при внесении и выборке.

mysql> select * from t;
+--------+-------------+
| id     | data        |
+--------+-------------+
| привет | привет мир! |
+--------+-------------+
1 row in set (0.00 sec)

Данные хранятся в разном виде, но поступают к пользователю именно так, как надо!

Подробнее с кодировками и проблемами их использования можно ознакомиться на http://dev.mysql.com/doc/refman/5.1/en/charset.html.

Кодировка HTML-страниц

Объявить кодировку html-страницы можно двумя способами: через заголовки и мета-тег в самой странице. Мета-тег используется только в статичных страницах.

<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">

Я не буду его разбирать, это проблемы html. Во всех остальных случаях предпочтительней использовать HTTP-заголовок Content-Type.

PHP позволяет работать с HTTP-заголовками посредством функции header():

// Объявление типа содержимого и его кодировки
header('Content-Type: text/html; charset=windows-1251');

Но браузер отобразит страницу корректно только в том случае, когда php-файлы сами были созданы в кодировке cp1251. Также нужно понимать, что заголовки должны быть отправлены до любого вывода на экран.

При необходимости перекодировать страницы «на лету», достаточно воспользоваться буферизацией и iconv:

Код - динамическая перекодировка
1
2
3
4
5
6
7
8
9
<?php
iconv_set_encoding('internal_encoding', 'WINDOWS-1251'); // Исходная кодировка файлов
iconv_set_encoding('output_encoding'  , 'UTF-8');        // Конечная кодировка
ob_start('ob_iconv_handler');                            // буферизация

header('Content-Type: text/html; charset=UTF8');
?>

Привет, мир!

Надпись «Привет, мир!» будет выведена в юникоде, при этом браузер получит информацию о кодировке через заголовки и правильно отобразит страницу. Но важно понимать, что внутри скрипта и при соединении с базой данных надо использовать windows-1251 (cp1251), поскольку страница должна быть сформирована в одной кодировке.

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

Заключение

Для безопасной разработки русскоязычных веб-проектов необходимо включать в файл с общими настройками следующие команды:

Код - файл общих настроек
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// Файл общих настроек
...

// Вывод заголовка с данными о кодировке страницы
header('Content-Type: text/html; charset=windows-1251');

// Настройка локали
setlocale(LC_ALL, 'ru_RU.CP1251', 'rus_RUS.CP1251', 'Russian_Russia.1251', 'russian');

// Настройка подключения к базе данных
mysql_query('SET names "cp1251"');

?>

Как ни странно, но эти три строчки кода значительно повышают портируемость веб-проектов.


От автора: вопрос кодировок является, без сомнения, одним из актуальных вопросов рано или поздно встающим перед любым веб-мастером. Практически каждый из нас сталкивался с такой, порой довольно неприятной, проблемой, как проблема корректного отображения информации на сайте, т.е. вывод ее на экран в нужной нам кодировке. Несмотря на то, что этот вопрос почти всегда решается очень легко, и ничего сложного в нем нет. Сейчас в сети можно часто увидеть вопросы о всевозможных «кракозябрах, вопросах и ромбиках» на сайте.

1. Кодировка при работе без использования баз данных

Забегая вперед, давайте сразу сформулируем основной тезис, придерживаясь которого мы значительно облегчим себе работу:

Кодировка в Вашем проекте должна быть универсальной.

Какое значение вкладывается в этот термин — «универсальная»? Это значит, что все составляющие создаваемого проекта, которые так или иначе касаются кодировок, должны иметь единую кодировку. Чтобы понять эту мысль разобьем сформулированный тезис на пункты, которые затем поэтапно разберем:

    1. Содержимое всех файлов должно иметь единую кодировку.

    2. Заголовки должны передавать единую кодировку.

    3. В качестве кодировки сервера необходимо установить единую кодировку.

    4. Кодировка соединения с БД также не должна отличаться от кодировки создаваемого проекта.

Это 4 основных правила, которые и являются составляющими сформулированного тезиса. Давайте теперь разберем каждый из этих пунктов.

Итак, на сервере создадим файл index.php, содержимое которого сохраним в кириллической кодировке. Сделать это можно, например, в редакторе Notepad++ через пункт меню Кодировки.

кодировка сайта

Узнать текущую кодировку файла можно взглянув в строку состояния редактора (в нижней панели).

кодировка сайта

Здесь уместно дать небольшой совет. При создании сайтов лучше пользоваться одной из двух кодировок: кириллической (windows-1251) или юникод без сигнатуры BOM (utf-8 without BOM). При этом следует знать, что юникод более универсален. Эта кодировка содержит большее количество символов, а потому идеально подойдет для мультиязычных сайтов, в то время как с кириллической кодировкой здесь могут возникнуть проблемы. Есть еще ряд нюансов при использовании юникода. В общем, лучше использовать ту кодировку, которая более универсальна, но если Ваш сайт содержит только кириллические символы, то никто не запрещает использовать Вам windows-1251, тем более, что она также имеет свои плюсы (детальнее об этом, возможно, в одном из следующих уроков).

Отлично, кодировка нашего файла кириллическая (windows-1251). У всех остальных файлов проекта, согласно первому пункту, кодировка должна быть аналогичной. В мета-тегах (между тегами head) также укажем эту кодировку:

<meta httpequiv=«content-type» content=«text/html; charset=windows-1251» />

Выведем какой-нибудь текст кириллицей на страницу:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Strict//EN»

    «//www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd»>

<html xmlns=«//www.w3.org/1999/xhtml»>

<head>

<meta httpequiv=«content-type» content=«text/html; charset=windows-1251» />

<meta name=«keywords» content=«» />

<meta name=«description» content=«» />

<title>Кодировки</title>

<link href=«» rel=«stylesheet» type=«text/css» />

</head>

<body>

<p>Тестовая строка</p>

</body>

</html>

Сохраним файл и попробуем открыть его в браузере… На экран выводится нечитабельная строка — набор вопросительных знаков вместо букв.

Почему так? Ведь мы сохранили файл в кириллической кодировке, в мета-теге также прописали нужную кодировку, но это не помогло. Если мы взглянем, в какой именно кодировке браузер отобразил нам текст, то увидим UTF-8.

кодировка сайта

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

«Виноват» здесь не браузер, а сервер. Дело в том, что сервер отсылает в браузер так называемые заголовки, где указывается кодировка, в которой браузер должен отобразить содержимое файла. В качестве кодировки сервер берет кодировку по умолчанию, т.е. так называемую дефолтную кодировку сервера. Посмотреть дефолтную кодировку сервера можно в конфигурационном файле httpd.conf, расположенном на сервере в каталоге usr\local\apache\conf\. Здесь кодировка задается в строке AddDefaultCharset. Здесь же мы можем изменить кодировку на нужную нам, при этом не забывая после внесения изменений перезапускать сервер.

Но изменить кодировку получится только на локальном сервере. На сервере в сети хостер нам просто не даст доступ к конфигурационному файлу сервера… и правильно сделает 🙂 Что же нам делать в таком случае? Неужели придется подстраиваться под настройки сервера? Конечно же нет. Для решения этой задачи существует 2 варианта, отвечающих за второй и третий сформулированные нами выше пункты.

Согласно второму пункту мы можем самостоятельно передать в заголовках необходимую кодировку. Делается это при помощи функции header(), в параметрах которой мы укажем тип документа и, собственно, кодировку. В самом верху файла (перед объявлением доктайпа (типа документа)) добавим строку кода:

<?php header(«Content-type: text/html; Charset=windows-1251»); ?>

Если теперь обновить страницу в браузере, то увидим читабельный текст в кириллической кодировке. Замечательно — мы решили задачу! Путем передачи заголовков мы указали нужную нам кодировку. Но этот вариант не совсем универсален. Дело в том, что заголовки передаются посредством функции header(), т.е. для этого мы используем средства PHP. Но что же тогда делать, если файлы нашего проекта имеют расширение html? В файлах с таким расширением по умолчанию код PHP не выполняется, соответственно — заголовки не будут отправлены. Результат — вновь нечитабельный текст в браузере.

Альтернативой является второе решение (пункт 3), которое гораздо более универсальнее первого. Итак, согласно пункта 3 мы должны установить дефолтной кодировкой сервера нужную нам. Но как это можно сделать, если к конфигурационному файлу сервера мы доступа не имеем? Очень просто. Предусмотрен специальный файл, в котором можно изменять некоторые настройки сервера, в частности — дефолтную кодировку. Файл этот не имеет расширения и называется .htaccess (с точкой в начале имени файла). В самом файле достаточно прописать ту же строку, что и в конфигурационном файле сервера, но с указанием необходимой кодировки:

AddDefaultCharset windows1251

Сервер при этом перезапускать не нужно, поскольку фактически мы ничего не изменяем в его настройках, а просто «говорим» серверу, что в качестве дефолтной кодировки следует использовать ту, которую мы только что указали.

Теперь файлы открываются в «правильной» (нужной нам) кодировке (функцию header() теперь нет надобности использовать) и кодировка нашего проекта не будет зависеть от настроек сервера того или иного хостера.
Но помните, если мы нарушим сформулированный нами тезис об универсальности кодировки и, к примеру, при установленной в качестве дефолтной кодировки кириллице перекодируем содержимое файлов в юникод, то получим знаменитые «кракозябры».

2. Проблема кодировки при работе с базой данных

Теперь взглянем на ту же проблему, но с использованием в работе БД. Дело в том, что в таблицах БД лежит текст, и эти таблицы также могут иметь свою кодировку. Поскольку я использую в качестве сервера Денвер, который настроен под кириллическую кодировку, то логично, что для хранения информации в БД по умолчанию используется также кириллическая кодировка.

Не будем ничего изменять в настройках и при создании БД и таблицы оставим все как есть, т.е. будет использована кириллическая кодировка. Хотя, забегая вперед, можно сказать, что если бы мы создали таблицы в нужной нам кодировке, то это совсем не означает, что данные будут выведены в этой же кодировке… вся хитрость в том, что здесь существует такой параметр, как кодировка соединения с БД. Вот ее то мы и будем использовать для достижения нужного результата.

Итак, создадим файл с кодировкой юникод (поскольку мы заранее знаем, что данные из БД будут выведены в кириллической кодировке), т.е. мы таким образом поставили перед собой в учебных целях проблему, которую и попытаемся решить… как говорится, тяжело в учении… 🙂

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<?php header(«Content-type: text/html; Charset=utf-8»); ?>

<!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Strict//EN»

    «//www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd»>

<html xmlns=«//www.w3.org/1999/xhtml»>

<head>

<meta httpequiv=«content-type» content=«text/html; charset=utf-8» />

<meta name=«keywords» content=«» />

<meta name=«description» content=«» />

<title>Кодировка при работе с БД</title>

<link href=«» rel=«stylesheet» type=«text/css» />

</head>

<body>

</body>

</html>

Теперь создадим БД charset и в ней таблицу test с двумя полями:

id, тип INT, первичный ключ, автоинкремент;

text, тип VARCHAR, длина 255.

В таблицу поместим единственную запись в поле text:

Эту запись мы и будем выводить на экран. Для этого пропишем соединение с сервером MySQL, выберем БД для работы и запросом выберем необходимые данные (все это мы уже проделывали в ряде предыдущих уроков, а потому подробно останавливаться на объяснении всего этого — нет оснований):

<?php

header(«Content-type: text/html; Charset=utf-8»);

mysql_connect(«localhost», «root», «») or die(«Can’t connect to server»);

mysql_query(«SET NAMES ‘utf8′») or die(«Can’t set charset»);

mysql_select_db(«charset») or die(«Can’t select DB»);

$res = mysql_query(«SELECT `text` FROM `test` WHERE `id`=». 1) or die(mysql_error());

$row = mysql_fetch_assoc($res);

?>

Теперь в массиве $row мы имеем искомую строку. Давайте выведем ее в теле страницы (между тегами body):

<?php

echo $row[‘text’];

?>

Если сейчас открыть страницу в браузере, то увидим опять-таки вместо читабельного текста вопросительные знаки. Так произошло оттого, что браузер (согласно отосланных заголовков) открыл страницу в юникоде, но информация из БД достается в кириллической кодировке. Как это исправить? Очень просто — достаточно после соединения с сервером БД указать в запросе кодировку соединения, тогда данные из БД будут отдаваться в искомой кодировке.

Пропишем необходимый запрос после соединения:

mysql_connect(«localhost», «root», «») or die(«Can’t connect to server»);

mysql_query(«SET NAMES ‘utf8′») or die(«Can’t set charset»);

Теперь после обновления страницы информация выводится корректно.
Вот и вся хитрость.

Заключение

Стоит обратить внимание на отличия в именовании кодировок в MySQL от традиционного их именования, т.е. того, к которому мы привыкли. Например, указать юникод правильно так — «utf8», но не так — «utf-8». Второй вариант серверу MySQL будет непонятен. Аналогично с кириллицей: правильно так — «cp1251», но не так — «windows-1251».

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

Надеюсь, данный урок был полезен для Вас. Если у Вас остались какие-либо вопросы, то я с удовольствием отвечу на них в комментариях.

Автор: Кудлай Андрей

Редакция: Рог Виктор и Андрей Бернацкий. Команда webformyself.

Кодировка данных, отправляемых формой

Данные, отправляемые формой имеют ту же кодировку, что и страница, на которой находится форма. Но как же быть, если страница например в кодировке UTF-8, а надо чтобы данные отправлялись в кодировке windows-1251. Конечно есть такой вариант, как сменить кодировку у страницы. Но это не всегда возможно, сайт — CMS уже настроена на работу с конкретной кодировкой.

Поменять кодировку отправляемых формой данных можно прописав у тега form атрибут accept-charset=»нужная кодировка». Например:

<form action=«» acceptcharset=«windows-1251»>

<input type=«text» name=«t» value=«» />

<input type=«submit» name=«s» value=«submit» />

</form>

В этом случае в независимости от кодировки страницы данные формы будут в кодировке windows-1251.

UPD

Но! Как выяснилось этот атрибут не поддерживается горячо «любимом» браузере Internet Explorer до 7 версии включительно.
В последующих реализовано, но имеются ошибки. Internet Explorer содержит ошибку при использовании кодировки ISO-8859-1, в этом случае браузер отправляет данные в кодировке Windows-1252.

К сожалению всё предыдущее решение ломается, так как этот браузер на данный момент игнорировать нельзя. Но думаю в скором будущем — через год, можно будет забыть про IE 6, так как его процент стремительно падает. Так же можно будет забыть IE7, так как к моей радости благодаря выпуску IE 8 он не обрёл такую большую популярность. Да и политика от мелкомягких к счастью сменилась. Выпускают более новые браузеры и от старых стараются отказываться.

Как бы то ни было, проблему с кодировкой кроссбраузерно можно решить следующим методом.

Подключаем в нужном месте на странице с кодировкой UTF-8 файл с формой посредством iframe. Подключаемый файл должен иметь нужную кодировку, например windows-1251. Тогда форма будет отправлять данные в нужной — windows-1251 кодировке.

Для красоты у iframe ставим высоту, ширину, чтобы форма была видна. Убираем скроллинг в любой ситуации. Убираем рамки. Это всё для того, чтобы не было видно, что форма находится в iframe.

<iframe src=«form.php» frameborder=«0» height=«250» width=«100%» scrolling=«no»></iframe>

У формы в подключаемом файле ставим target=»_parent». У подключаемого файла ставим нужную кодировку в метатегах.

Иногда браузер игнорирует установку кодировки из метатегов, так как сервер приказывает браузеру установить другую кодировку посредством HTTP заголовков. Да, для браузера приоритетнее HTTP заголовки, чем метатеги. Для этого делаем подключаемый файл сделаем скриптом .php и в начале файла пишем следующее:

<?php

header(«Content-Type: text/html; charset=windows-1251»);

?>

Теги: accept-charset, browser, charset, cross-browser, form, IE, iframe, microsoft, PHP, браузер, кроссбраузерность, проблема

Кодировка 1251 является одной из наиболее распространенных в России и странах бывшего СССР. Она используется для отображения текста на русском языке, украинском языке и других языках, использующих кириллицу. Для того, чтобы указать серверу, что нужно использовать именно эту кодировку при отправке ответа на запрос, в PHP используется функция header().

Пример кода:

header('Content-Type: text/html; charset=windows-1251');
echo 'Текст на русском языке';

В данном примере мы указываем, что тип содержимого, который будет отправлен на страницу, является текст/html, а кодировка — windows-1251. Затем выводим текст на русском языке с помощью команды echo().

Если необходимо изменить кодировку страницы внутри уже открытого документа, можно использовать следующий код:

header('Content-Type: text/html; charset=windows-1251');
header('Content-Language: ru');
echo 'Заголовок страницы...';

В этом примере мы указываем кодировку и язык страницы с помощью двух header-заголовков, а затем выводим HTML-код с помощью команды echo().

Недостатки PHP-Fusion. Если сайт вопросительными знаками сделать кодировку cp1251

Кодировки ANSI, UTF-8 и Unicode — Чем отличаются?

16 Функция header в PHP

HTML : Charset UTF-8 and php header() not working

UTF-8 и mbstring в PHP — Базовый курс PHP-7

PHP : How to set HTTP header to UTF-8 using PHP which is valid in W3C validator

PHP 8.1.0-dev Backdoor Remote Code Execution — RCE — PoC — FLAST101

Приветствую!

Подскажите, пожалуйста, каким образом можно исправить кодировку получаемого текста?
По запросу

$content = file_get_contents('http://vk.com/foaf.php?id=1');

мне нужна строчка из <foaf:name></foaf:name>
Сам код выглядит

так:

<?
$content = file_get_contents('http://vk.com/foaf.php?id=1');
preg_match_all('#<foaf:name>(.+?)</foaf:name>#is', $content, $arr);
print_r($arr[1]);
?>

или

так:

<?
$content = file_get_contents('http://vk.com/foaf.php?id=529113');
$pos = strpos($content, '<foaf:name>');
$content = substr($content, $pos);
$pos = strpos($content, '</foaf:name>');
$content = substr($content, 0, $pos);
$content = str_replace('текст который нужно вырезать','', $content);
//$content = iconv("utf-8","windows-1251",$content); //Смена кодировки
print $content;
?>

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

Что пробовал:
Менял кодировку с utf-8 на windows-1251. Прописывал в исходном файле

<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">.

, указывал в коде

<?header("Content-type:text/html; charset=windows-1251");?>

. Менял кодировку самого файла. В коде пробовал менять кодировку возможностями самого php

$content1 = iconv("utf-8","windows-1251",$content); //Смена кодировки

Создавал .htacces. В нем писал AddDefaultCharset windows-1251 и PHP_VALUE default_charset windows-1251

Но результат один, несчастные знаки ������ �������…

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Как изменить имя принтера в windows 7
  • Приложение для звонков windows
  • Windows 7 при установке требует драйвер для привода cd dvd или usb
  • Где находится java в windows 10
  • Djvu reader for windows xp