різні кодування в php
початківцям скріптопісателям глибоко плювати на таке поняття, як кодування. тому на сайтах іноді можна зустріти страшну кашу, коли дані з бд виходять в одному кодуванні, сторінка формується в інший, а сервером віддається третя. в результаті сторінку якщо і можна розшифрувати, то мінімум з 2 раз. отже, чому ж така біда трапляється і як її подолати?
в російській сегменті найчастіше можна зустріти так звану windows-кодування. називають її по різному: windows-1251, cp1251 або навіть ansi. Наступного йде utf-8. можна зустріти також назва unicode, але це не зовсім коректно, т. к. юнікод загальна назва для цілої групи (utf-8, utf-16, utf-32). і вже зовсім раритетом є популярна koi8-r або просто вряди-8 - колись популярна лінуксовская кодування. звичайно, можна в російській сегменті зустріти і щось інше, але це скоріше є «пустощами» автором.
основна відмінність utf-8 від інших (в першу чергу windows-1251 і koi8-r) - останні є однобайтового, і максимальну кількість символів, які можна представити за допомогою даних кодувань обмежити числом 256. само-собою, що для повноцінного представлення тексту цього може бути недостатньо. і для html був знайдений вихід - використання так званих мнемонік. наприклад, так:
© - & copy;
крім того, що кожен такий символ описується групою символів, код стає малочітаемом і робота з текстом ускладнюється. тут-то і приходить на допомогу мультибайтних utf-8. дуже зручно в одному тексті використовувати букви різних алфавітів і різні символи.
таким чином, найбільш комфортний набір початкових умов такої: кодування бази даних, php-скриптів і html-сторінок / js-скриптів повинна бути однією і тією ж. звичайно, можна використовувати і різні, але в цьому випадку є ризик заплутатися. при цьому не важливо, яка саме кодова сторінка використовується. якщо сайт буде тільки для російськомовної аудиторії, windows-1251 буде цілком достатньо. інакше логічним вибором буде utf-8. з першим варіантом все більш-менш зрозуміло. а для багатобайтові кодування будуть потрібні деякі рухи тіла.
при роботі з utf-8 стандартний віндусовскій notepad не підійде! справа в тому, що даний редактор, при збереженні файлу в цьому кодуванні, додає в початок сигнатуру - 3 символу, так званий bom (byte order mark), по якому при відкритті файлу можна визначити кодування. краще вибрати інший редактор: notepad2 або notepad ++ . в настройках обов'язково вибрати збереження без сигнатури.
наступний важливий крок - робота з базою даних. вкрай бажано, щоб кодування бази / таблиці / текстового поля збігалися з кодуванням скрипта (це може бути cp1251 або utf-8, або що-небудь інше). якщо дані з бази виходять у вигляді «Зюков», швидше за все кодування з'єднання відрізняється від даних, що зберігаються в бд. Наступного запит допоможе побороти ситуацію (виконати відразу після з'єднання з базою):
якщо на сайті використовується windows-1251, слід вказати її - cp1251.
в общем-то, немає нічого складного. єдино, стандартні функції php не призначені для роботи з мультибайтних рядками. але є стандартні бібліотеки, які допоможуть виправити ситуацію: iconv і mbstring . для регулярних виразів також існує необхідний перемикач, який активується за допомогою модифікатора u.
що ж, дані з бази отримані, скрипти написані за всіма правилами. залишається відіслати правильний заголовки і вивести код сторінки в браузер користувача. заголовок посилаємо так:
header ( 'Content-Type: text / html; charset = utf-8');
якщо використовується однобайтового кодування, то значення для charset буде іншим - windows-1251. після цього проблем залишитися не повинно.
кілька найпростіших прикладів роботи з utf-8 на php:
приклад 1: iconv, кількість символів в рядку
$ S = 'рядок'; # Рядок в utf-8 $ cnt1 = strlen ($ s); # Буде містити значення 12 $ cnt2 = iconv_strlen ($ s, 'UTF-8'); # Правильне значення, 6
приклад 2: mbstring, кількість символів в рядку
$ S = 'рядок'; # Рядок в utf-8 $ cnt1 = strlen ($ s); # Буде містити значення 12 $ cnt2 = mb_strlen ($ s, 'UTF-8'); # Правильне значення, 6
приклад 3: регулярні вирази, пошук і заміна
$ S = 'Рядок'; # Рядок в utf-8 $ s = preg_replace ( '/ стр / i', 'д', $ s); # Заміна не відбудеться $ s = preg_replace ( '/ стр / iu', 'д', $ s); # Результат слово дока
модифікатор i наказує регістронезавісімий пошук, а модифікатор u говорить движку регулярних виразів працювати з utf-8 рядками.
якщо хтось скаже, що php не може працювати з utf-8, він буде не правий. вже кілька років роблю всі свої проекти в цьому кодуванні і проблем не було зовсім. пошукові системи самі давно використовують цю чудову кодування.
Автор публікації
не в мережі 11 годин
x64 (aka andi)
Коментарі: 2846 Публікації: 395 Реєстрація: 02-04-2009
Отже, чому ж така біда трапляється і як її подолати?