Локали и кодировки
При разработването на уеб приложения има три важни момента, свързани с кодирането: информация в скриптовите файлове, информация в базата данни и браузъра на потребителя. Ако поне едно кодиране е зададено неправилно, тогава в най-добрия случай данните ще се показват неправилно, в най-лошия случай ще бъдат безвъзвратно загубени. За да предотвратите това да се случи и приложението да работи правилно с всякакви настройки на сървъра, трябва да зададете правилно кодировките.
Работа с локали в PHP
Локали в Windows
За да разберете какви локали са налични в Windows, трябва да отидете в контролния панел, „Регионални и езикови опции“.
Разделът „Разширени“, раздел „Кодови страници на таблица за преобразуване“, показва списък с всички възможни локали на Windows, които могат да се използват в PHP.
Кодовите страници, които са маркирани в списъка от PHP, могат да се използват по техния номер.
Най-общо използването изглежда така: Language_Region.Code_page номер
За България това може да изглежда като Russian_Russia.1251 (cp1251) или Russian_Russia.20866 (KOI8-R).
За Украйна - Ukrainian_Ukraine.1251 (cp1251).
Вместо дълги имена можете да използвате съкратени руски, американски, украински и т.н. В този случай кодовата страница ще бъде зададена, като се вземат предвид регионалните настройки, за България и Украйна - 1251, за Америка - 1252.
Засега това може да се отдаде на вътрешния механизъм на PHP за работа с низове. От PHP 6 цялата обработка на низове ще трябва да бъде в UTF-8, но дотогава просто трябва да сте наясно с това и да правите корекции.
Като цяло, това може да е краят на разговора за локалите на Windows. Основното нещо, което трябва да запомните е, че локалите, които са пренесени от UNIX, работят под WIndows само за показ. стъпканаляво, стъпете надясно и резултатът ще бъде непредвидим. Само cp1251 (windows-1251) и KOI8-R могат да се използват безопасно и само за LC_ALL.
Локали в UNIX
По-горе описах работата с локали в Windows, сега можете да се съсредоточите върху UNIX-подобни системи. За простота ще ги нарека UNIX и ще имам предвид FreeBSD :). В контекста на тази статия това не е особено важно.
И така, дистрибуциите на UNIX се доставят в една форма за всички и работата е предназначена за многопотребителски режим, така че самият потребител трябва да се погрижи за правилната настройка на локала, например:
Ето как може да изглежда системната команда за локализация, която показва текущите настройки за локализация за потребителя. И така, обикновено локалните настройки за потребителя, под който работи PHP, изглеждат така:
Функцията ucwords() трябваше да изписва с главни букви първите букви на всички думи. А преди това strtolower() трябваше първо да направи всички главни букви малки. Но нищо не се случи. Следният код също няма да работи:
Въпреки че \w е набор от знаци, от които може да се състои една дума (азбука, цифри и _), регулярният израз не работи. Причината е просто, че когато работихме с cp1251, не казахме на php за това. За да коригирате ситуацията, достатъчно е да използвате функцията setlocale() и да посочите правилния локал, например по следния начин:
С командата grep избрах локалите, които поддържат български език. Всеки от тях може да се използва, но трябва да се разбере, че данните трябва да бъдат в кодирането, за което е проектиран локалът. Ако това правило не се спазва, тогава резултатът може да бъде доста неочакван:
Като се има предвид, че koi8-r е доста популярно кодиране за UNIX сървъри, а windows-1251 за сайтове на български език, тогава нещо подобно„Необичайното“ поведение не е необичайно. Веднъж аз самият се сблъсках с този проблем, когато пренасях проект към истински хостинг.
След като зададете правилния локал, всички примери, които не са работили по-горе, ще работят както трябва!
Функцията strftime(), която работи коректно с локали, също ще говори български, както и всичко останало, което зависи от локала.
MySQL кодировки
Позволете ми да ви напомня, че възможността за задаване на кодировки се появи само в MySQL 4.1.11 и по-нови.
Първото нещо, което трябва да научите, е да погледнете текущите настройки на mysql връзката:
Критични за потребителя са character_set_client и character_set_results, които отговарят за кодирането, в което данните влизат в базата данни, и кодирането, в което данните идват от базата данни до потребителя. Ако тези две кодировки се различават от тази, в която работи клиентът, в нашия случай php скриптове, тогава неизбежно ще има "странности", например при сортиране на селекция или въвеждане на данни в базата данни.
Второто нещо, което трябва да знаете, е как правилно да кажете на mysql за кодировките. Най-простият и правилен начин е да използвате заявката за имена на набори:
След това трите променливи character_set_client, character_set_connection и character_set_results ще бъдат зададени на cp1251. Това ще означава, че клиентът работи в Windows-1251 (cp1251) кодиране.
Освен това можете директно да задавате сървърни променливи:
Сега данните се получават и извличат в различни кодировки.
И третото нещо, което трябва да знаете, са правилата за създаване на таблици за съхраняване на данни в желаното кодиране. Между другото, данните могат да се съхраняват във всяко кодиране и да работят с тях в кодирането на клиента. Важно е обаче да се разбере, че кодировките имат национален характер и трябва да отговарят на въведенитеданни. В противен случай ще има загуби. За българския език има три национални кодировки koi8r, cp866, cp1251, които могат да се конвертират едно в друго без загуба. Можете също да използвате международно кодиране UTF8.
Кодирането може да бъде зададено за базата данни, таблицата и полето на таблицата. Така например можете да създадете база данни в кодиране koi8r:
Трябва да се отбележи, че кодирането на базата данни засяга само стойностите на кодиране по подразбиране при създаване на таблици. Това означава, че няма значение в какво кодиране е създадена базата, ако кодирането на таблицата е зададено изрично. Същото правило важи и за полетата на таблицата.
В следващата стъпка ще създам таблица в cp1251 и едно поле в utf8:
След като таблицата е създадена с необходимите опции за кодиране, mysql автоматично започва да превежда данните по време на вмъкване и избор.
Данните се съхраняват в различна форма, но идват до потребителя точно както трябва!
За повече информация относно кодировките и проблемите с тяхното използване вижте http://dev.mysql.com/doc/refman/5.1/en/charset.html.
Кодиране на HTML страници
Има два начина за деклариране на кодирането на html страница: чрез заглавки и мета таг в самата страница. Мета тагът се използва само на статични страници.
Няма да го анализирам, това са проблеми с html. Във всички останали случаи е за предпочитане да използвате HTTP заглавката Content-Type.
PHP ви позволява да работите с HTTP заглавки чрез функцията header():
Но браузърът ще покаже страницата правилно само ако самите php файлове са създадени в cp1251 кодиране. Трябва също така да разберете, че заглавките трябва да бъдат изпратени преди изхода на екрана.
Ако трябва да прекодирате страници в движение, просто използвайте буфериране и iconv:
Надписът "Hello world!" ще се показва в unicode, докато браузърът ще получи информация за кодирането чрез заглавките и ще покаже страницата правилно. Но е важно да разберете, че вътре в скрипта и когато се свързвате с базата данни, трябва да използвате windows-1251 (cp1251), тъй като страницата трябва да се формира в едно кодиране.
Важно е да запомните, че функциите iconv не винаги са налични и проверката за наличността на тези функции няма да бъде излишна.
Заключение
За безопасното разработване на уеб проекти на български език във файла с общи настройки трябва да има следните команди:
Колкото и да е странно, тези три реда код значително увеличават преносимостта на уеб проектите.