HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <h2>Юникод</h2>
1 <h2>Юникод</h2>
2 <p>Данные программы хранятся в памяти компьютера в виде последовательности нулей и единиц. На этом уровне нет разницы между строками, числами или булевыми значениями. В памяти все выглядит одинаково. Разница появляется только в результате интерпретации.</p>
2 <p>Данные программы хранятся в памяти компьютера в виде последовательности нулей и единиц. На этом уровне нет разницы между строками, числами или булевыми значениями. В памяти все выглядит одинаково. Разница появляется только в результате интерпретации.</p>
3 <p>Программа знает, что внутри некоторой переменной хранится строка, поэтому она берет нули и единички и пропускает их сквозь кодовую таблицу. В ней указано, какому числу соответствует какая буква. В результате программист видит строку. В этом уроке мы обсудим, как работают такие кодовые таблицы.</p>
3 <p>Программа знает, что внутри некоторой переменной хранится строка, поэтому она берет нули и единички и пропускает их сквозь кодовую таблицу. В ней указано, какому числу соответствует какая буква. В результате программист видит строку. В этом уроке мы обсудим, как работают такие кодовые таблицы.</p>
4 <p>В самом начале была только<a>ASCII</a>- кодировка, основанная на английском алфавите.</p>
4 <p>В самом начале была только<a>ASCII</a>- кодировка, основанная на английском алфавите.</p>
5 <p>В этой кодировке одному символу соответствует 7 бит, всего в ней закодировано 128 символов:</p>
5 <p>В этой кодировке одному символу соответствует 7 бит, всего в ней закодировано 128 символов:</p>
6 <ul><li>95 печатных символов, включая буквы алфавита в верхнем и нижнем регистрах, цифры и знаки препинания</li>
6 <ul><li>95 печатных символов, включая буквы алфавита в верхнем и нижнем регистрах, цифры и знаки препинания</li>
7 <li>33 непечатных символа (управляющих кода)</li>
7 <li>33 непечатных символа (управляющих кода)</li>
8 </ul><p>Большинство непечатных символов сейчас не актуальны, но некоторые по-прежнему используются - например, перевод строки \n.</p>
8 </ul><p>Большинство непечатных символов сейчас не актуальны, но некоторые по-прежнему используются - например, перевод строки \n.</p>
9 <p>Символы в ASCII можно перекодировать. Например, символ i в нижнем регистре соответствует:</p>
9 <p>Символы в ASCII можно перекодировать. Например, символ i в нижнем регистре соответствует:</p>
10 <ul><li>Числу 1101001 в двоичной системе счисления</li>
10 <ul><li>Числу 1101001 в двоичной системе счисления</li>
11 <li>Числу 105 в десятичной системе</li>
11 <li>Числу 105 в десятичной системе</li>
12 </ul><p>Поначалу все было хорошо, но с распространением компьютеров возникла потребность в других алфавитах. Каждая страна решала данную проблему созданием собственной кодировки, большинство из которых совместимы с ASCII:</p>
12 </ul><p>Поначалу все было хорошо, но с распространением компьютеров возникла потребность в других алфавитах. Каждая страна решала данную проблему созданием собственной кодировки, большинство из которых совместимы с ASCII:</p>
13 <ul><li>Первые 128 символа полностью соответствовали ASCII</li>
13 <ul><li>Первые 128 символа полностью соответствовали ASCII</li>
14 <li>Остальные 128 - заполнялись локальным алфавитом</li>
14 <li>Остальные 128 - заполнялись локальным алфавитом</li>
15 </ul><p>В итоге в таких кодировках было 256 символов, а это 2 в 8 степени.</p>
15 </ul><p>В итоге в таких кодировках было 256 символов, а это 2 в 8 степени.</p>
16 <p>Эти кодировки были однобайтовыми - для хранения одного символа требовался один байт. Но внезапно возникла проблема: попытка открыть в редакторе файл в другой кодировке приводила к появлению<a>"кракозябр"</a>:</p>
16 <p>Эти кодировки были однобайтовыми - для хранения одного символа требовался один байт. Но внезапно возникла проблема: попытка открыть в редакторе файл в другой кодировке приводила к появлению<a>"кракозябр"</a>:</p>
17 <blockquote><p>Øèðîêàÿ ýëåêòðèôèêàöèÿ þæíûõ ãóáåðíèé äàñò ìîùíûé òîë÷îê ïîäú¸ìó ñåëüñêîãî õîçÿéñòâà</p>
17 <blockquote><p>Øèðîêàÿ ýëåêòðèôèêàöèÿ þæíûõ ãóáåðíèé äàñò ìîùíûé òîë÷îê ïîäú¸ìó ñåëüñêîãî õîçÿéñòâà</p>
18 </blockquote><p>Возникают они потому, что один и тот же код в разных кодировках соответствует совершенно разным символам, за исключением первых 128. Поэтому текст, использующий английские буквы всегда читался, а в остальном - как повезет. Ситуация усугублялась тем, что даже в рамках одного алфавита создавалось множество разных кодировок, например: Windows-1252, KOI8-R, CP 866, ISO 8859-5.</p>
18 </blockquote><p>Возникают они потому, что один и тот же код в разных кодировках соответствует совершенно разным символам, за исключением первых 128. Поэтому текст, использующий английские буквы всегда читался, а в остальном - как повезет. Ситуация усугублялась тем, что даже в рамках одного алфавита создавалось множество разных кодировок, например: Windows-1252, KOI8-R, CP 866, ISO 8859-5.</p>
19 <p>В языках программирования на тот момент все функции для работы со строками создавались из расчета, что один символ - это один байт. По крайней мере, это свойство было общим для всех кодировок.</p>
19 <p>В языках программирования на тот момент все функции для работы со строками создавались из расчета, что один символ - это один байт. По крайней мере, это свойство было общим для всех кодировок.</p>
20 <p>Разные кодировки стали причиной постоянных проблем при взаимодействии людей и программ. Особенно остро эта проблема проявилась с развитием интернета. Такая ситуация не могла продолжаться бесконечно, и в конце концов был создан стандарт<strong>Юникод</strong>(<em>Unicode</em>).</p>
20 <p>Разные кодировки стали причиной постоянных проблем при взаимодействии людей и программ. Особенно остро эта проблема проявилась с развитием интернета. Такая ситуация не могла продолжаться бесконечно, и в конце концов был создан стандарт<strong>Юникод</strong>(<em>Unicode</em>).</p>
21 <p>Сейчас он содержит более 100 тысяч символов и включает в себя все существующие языки, даже мертвые. Стандарт Юникод не является кодировкой и ничего не говорит о том, как должны храниться символы в памяти, он лишь определяет связь между символом и некоторым числом.</p>
21 <p>Сейчас он содержит более 100 тысяч символов и включает в себя все существующие языки, даже мертвые. Стандарт Юникод не является кодировкой и ничего не говорит о том, как должны храниться символы в памяти, он лишь определяет связь между символом и некоторым числом.</p>
22 <p>Конкретный способ кодирования Юникода определяется соответствующими кодировками, среди которых есть UTF-8, UTF-16 и некоторые другие. В этих кодировках для хранения одного символа уже недостаточно одного байта, они используют больше. UTF-8 ведет себя хитрее: для символов английского алфавита и некоторых других используется один байт, для других алфавитов - два байта.</p>
22 <p>Конкретный способ кодирования Юникода определяется соответствующими кодировками, среди которых есть UTF-8, UTF-16 и некоторые другие. В этих кодировках для хранения одного символа уже недостаточно одного байта, они используют больше. UTF-8 ведет себя хитрее: для символов английского алфавита и некоторых других используется один байт, для других алфавитов - два байта.</p>
23 <p>После многих лет популяризации Юникода свершилось чудо, и сейчас подавляющее большинство программного обеспечения использует UTF-8. Этот процесс был болезненный и по-разному отразился на языках программирования. Например, в PHP стандартные функции не поддерживают многобайтовые кодировки:</p>
23 <p>После многих лет популяризации Юникода свершилось чудо, и сейчас подавляющее большинство программного обеспечения использует UTF-8. Этот процесс был болезненный и по-разному отразился на языках программирования. Например, в PHP стандартные функции не поддерживают многобайтовые кодировки:</p>
24 <p>Языки разделились на два лагеря. Одни языки встроили поддержку в уже существующие функции - в итоге переход на UTF-8 никак не отразился на процессе программирования. Среди таких языков есть Java, Ruby, JavaScript.</p>
24 <p>Языки разделились на два лагеря. Одни языки встроили поддержку в уже существующие функции - в итоге переход на UTF-8 никак не отразился на процессе программирования. Среди таких языков есть Java, Ruby, JavaScript.</p>
25 <p>А вот PHP пошел своим путем. Для работы с многобайтовыми кодировками в язык добавили отдельное<a>расширение по работе с многобайтовыми строками</a>. По большей части оно добавляет множество функций для работы со строками, с той лишь разницей, что каждая функция из них имеет префикс mb_ (<em>multibyte</em>):</p>
25 <p>А вот PHP пошел своим путем. Для работы с многобайтовыми кодировками в язык добавили отдельное<a>расширение по работе с многобайтовыми строками</a>. По большей части оно добавляет множество функций для работы со строками, с той лишь разницей, что каждая функция из них имеет префикс mb_ (<em>multibyte</em>):</p>
26 <p>А вот достойной альтернативы взятию конкретного символа в строке по индексу не существует. Такую задачу нужно выполнять с помощью функции mb_substr():</p>
26 <p>А вот достойной альтернативы взятию конкретного символа в строке по индексу не существует. Такую задачу нужно выполнять с помощью функции mb_substr():</p>
27 <h2>Локализация</h2>
27 <h2>Локализация</h2>
28 <p>Глобализация проявляется во многих аспектах, в том числе в единой системе мер: время, размеры и расстояния, температуры, даты и многое другое.</p>
28 <p>Глобализация проявляется во многих аспектах, в том числе в единой системе мер: время, размеры и расстояния, температуры, даты и многое другое.</p>
29 <p>Конечно, есть страны, которые выпадают из общего потока. Например, США - это чуть ли не единственная страна, в которой сохраняется и превалирует<a>английская система мер</a>. США использует мили вместо километров и фунты вместо килограммов. Во многих восточных странах по-другому устроены календари, и где-то сейчас идет четырехтысячный год. Но в целом все унифицировано.</p>
29 <p>Конечно, есть страны, которые выпадают из общего потока. Например, США - это чуть ли не единственная страна, в которой сохраняется и превалирует<a>английская система мер</a>. США использует мили вместо километров и фунты вместо килограммов. Во многих восточных странах по-другому устроены календари, и где-то сейчас идет четырехтысячный год. Но в целом все унифицировано.</p>
30 <p>Несмотря на эту унификацию, в каждой стране есть свои особенности по способу записи, сравнению и другим аспектам. Например, в США принято в датах первым ставить месяц, а вторым - день. В некоторых странах для вывода вещественных чисел используют точку, а в некоторых - запятую: 1,234.</p>
30 <p>Несмотря на эту унификацию, в каждой стране есть свои особенности по способу записи, сравнению и другим аспектам. Например, в США принято в датах первым ставить месяц, а вторым - день. В некоторых странах для вывода вещественных чисел используют точку, а в некоторых - запятую: 1,234.</p>
31 <p>Эти особенности необязательно привязаны к целой стране. Внутри одной страны может быть множество дополнительных разделений. Каждый такой набор особенностей называют<strong>локалью</strong>, а процесс адаптации к особенностям конкретной локали -<strong>локализацией</strong>.</p>
31 <p>Эти особенности необязательно привязаны к целой стране. Внутри одной страны может быть множество дополнительных разделений. Каждый такой набор особенностей называют<strong>локалью</strong>, а процесс адаптации к особенностям конкретной локали -<strong>локализацией</strong>.</p>
32 <p>Локализация важна в программном обеспечении. Пользователь всегда ожидает, что любой софт или сайт будет работать предсказуемо. В это понятие включается и локализация. Понятно, что самостоятельное решение этой задачи слишком затратно. К счастью, этого делать не нужно. Локализация обычно встроена в сам язык или в специальные библиотеки.</p>
32 <p>Локализация важна в программном обеспечении. Пользователь всегда ожидает, что любой софт или сайт будет работать предсказуемо. В это понятие включается и локализация. Понятно, что самостоятельное решение этой задачи слишком затратно. К счастью, этого делать не нужно. Локализация обычно встроена в сам язык или в специальные библиотеки.</p>
33 <p>В PHP для управления локалью используется функция<a>setlocale()</a>. Эта функция настраивает локаль глобально. Ее вызов влияет на все последующие функции, опирающиеся на локализацию:</p>
33 <p>В PHP для управления локалью используется функция<a>setlocale()</a>. Эта функция настраивает локаль глобально. Ее вызов влияет на все последующие функции, опирающиеся на локализацию:</p>
34 <p>Первым параметром эта функция принимает название категории (как константу), к которой нужно применить локаль, передающуюся в параметрах дальше:</p>
34 <p>Первым параметром эта функция принимает название категории (как константу), к которой нужно применить локаль, передающуюся в параметрах дальше:</p>
35 <ul><li>LC_ALL - все нижеперечисленное</li>
35 <ul><li>LC_ALL - все нижеперечисленное</li>
36 <li>LC_COLLATE - функции сравнения строк strcoll()</li>
36 <li>LC_COLLATE - функции сравнения строк strcoll()</li>
37 <li>LC_CTYPE - функции преобразования и классификации строк, например, strtoupper()</li>
37 <li>LC_CTYPE - функции преобразования и классификации строк, например, strtoupper()</li>
38 <li>LC_MONETARY - для функции localeconv()</li>
38 <li>LC_MONETARY - для функции localeconv()</li>
39 <li>LC_NUMERIC - задает символ десятичного разделения localeconv()</li>
39 <li>LC_NUMERIC - задает символ десятичного разделения localeconv()</li>
40 <li>LC_TIME - форматирование даты и времени функцией strftime()</li>
40 <li>LC_TIME - форматирование даты и времени функцией strftime()</li>
41 </ul><p>Изучим на примере, как установленная локаль влияет на отображение данных:</p>
41 </ul><p>Изучим на примере, как установленная локаль влияет на отображение данных:</p>
42 <p>Попробуем вторым аргументом передать 0 вместо локали: setlocale(LC_ALL, 0). В таком случае функция будет возвращать текущую установленную локаль для категории.</p>
42 <p>Попробуем вторым аргументом передать 0 вместо локали: setlocale(LC_ALL, 0). В таком случае функция будет возвращать текущую установленную локаль для категории.</p>
43 <h2>Поиск стартовой позиции</h2>
43 <h2>Поиск стартовой позиции</h2>
44 <p>Часто в работе со строками нужно определить, является ли одна строка<strong>подстрокой</strong>- частью другой строки. В большинстве языков программирования есть встроенная функция, предназначенная именно для этой задачи.</p>
44 <p>Часто в работе со строками нужно определить, является ли одна строка<strong>подстрокой</strong>- частью другой строки. В большинстве языков программирования есть встроенная функция, предназначенная именно для этой задачи.</p>
45 <p>В PHP такая функция появилась лишь в восьмой версии. До этого ее имитировали с помощью функции<a>mb_strpos()</a>. Эта функция ищет позицию первого вхождения одной строки в другую. Пока мы будем использовать именно mb_strpos():</p>
45 <p>В PHP такая функция появилась лишь в восьмой версии. До этого ее имитировали с помощью функции<a>mb_strpos()</a>. Эта функция ищет позицию первого вхождения одной строки в другую. Пока мы будем использовать именно mb_strpos():</p>
46 <p>В примере выше функция вернет 6, что соответствует индексу буквы М:</p>
46 <p>В примере выше функция вернет 6, что соответствует индексу буквы М:</p>
47 <p>А в этом примере вернется 0, что соответствует первой букве строки. В этом коде скрыта ошибка, которую часто допускают новички. В PHP 0 рассматривается, как false - значит, условие не выполнится. Правильная проверка выглядит так:</p>
47 <p>А в этом примере вернется 0, что соответствует первой букве строки. В этом коде скрыта ошибка, которую часто допускают новички. В PHP 0 рассматривается, как false - значит, условие не выполнится. Правильная проверка выглядит так:</p>
48 <p>Функция mb_strpos() возвращает false, если подстрока не была найдена. Значит, можно воспользоваться строгим сравнением с false.</p>
48 <p>Функция mb_strpos() возвращает false, если подстрока не была найдена. Значит, можно воспользоваться строгим сравнением с false.</p>