Last active
March 25, 2019 01:18
-
-
Save codedokode/ff99e357e9860ea169b8 to your computer and use it in GitHub Desktop.
Revisions
-
codedokode revised this gist
Jun 22, 2018 . 1 changed file with 4 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,7 @@ Статья переехала в мой гитхаб: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md . Ниже идет устаревшая и неточная версия. --- Некоторые функции PHP (`strlen`, `substr`, а также обращение к строке как к массиву: `$str[0]`) не работают с многобайтовыми кодировками (вроде utf-8). В utf-8 1 символ закодирован с помощью от 1 до 6 байтов, а эти функции думают, что 1 буква всегда кодируется одним байтом. По этой причине они ломают символы, в результате получаются битые символы и ничего не работает. Потому вместо них надо использовать mb_ функции например `mb_strlen`, `mb_substr`. Вместо доступа к строке как к массиву надо использовать `mb_substr`. Если тебе интересно, почему эти функции поддерживают только однобайтные кодировки, а не многобайтные, то причина в том, что они очень старые и написаны в то время (лет 40 назад) когда utf-8 и многобайтных кодировок еще не было. -
codedokode revised this gist
Dec 20, 2014 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,6 +16,8 @@ Латинница и цифры кодируются в utf-8 одним байтом, с ними это работает, но все равно, не надо использовать эти функции — это слишком ненадежно и легко сделать ошибку. Также, чтобы работать с русскими (и другими нелатинскими) буквами в регулярках, надо ставить в конце флаг `u`: `preg_match("/[абвг]/u", $string)`. Иначе `preg_match` будет думать что работает с однобайтной кодировкой и будет видеть не одну букву, а 2 latin1-символа (так как русская буква кодируется как 2 байта). Например, буква `л` кодирующаяся как `208 187` будет восприниматься как 2 символа с кодами `208` и `187`, то есть `л` (кодировка latin-1: http://en.wikipedia.org/wiki/ISO/IEC_8859-1#Codepage_layout ). Таким образом, регулярка будет работать некорректно и найдет не то. Вывод: используй `mb_*` функции. Не используй доступ к строке как к массиву. В регулярных выражениях используй флаг `u` (он говорит что используется utf-8 а не однобайтовая кодировка). Некоторые строковые функции без префикса mb тем не менее корректно работают с utf-8 и их можно использовать. Вот они: `strtr` (если передавать массив), `str_replace`, `str_repeat`, `explode`, `addslashes`, `trim`. -
codedokode revised this gist
Nov 16, 2014 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -20,7 +20,7 @@ Некоторые строковые функции без префикса mb тем не менее корректно работают с utf-8 и их можно использовать. Вот они: `strtr` (если передавать массив), `str_replace`, `str_repeat`, `explode`, `addslashes`, `trim`. **Не** работают с utf-8: `strrev`, `strlen`, `substr`, `strpos`, `ucfirst`, `wordwrap`, `str_pad` и большинство других строковых функций, для работы которых нужно считать число символов. Не работает задание ширины в функциях вроде `sprintf` и `printf`. ## mbstring.func_overload -
codedokode revised this gist
Nov 16, 2014 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,7 +16,7 @@ Латинница и цифры кодируются в utf-8 одним байтом, с ними это работает, но все равно, не надо использовать эти функции — это слишком ненадежно и легко сделать ошибку. Вывод: используй `mb_*` функции. Не используй доступ к строке как к массиву. В регулярных выражениях используй флаг `u` (он говорит что используется utf-8 а не однобайтовая кодировка). Некоторые строковые функции без префикса mb тем не менее корректно работают с utf-8 и их можно использовать. Вот они: `strtr` (если передавать массив), `str_replace`, `str_repeat`, `explode`, `addslashes`, `trim`. -
codedokode revised this gist
Nov 16, 2014 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,7 +16,7 @@ Латинница и цифры кодируются в utf-8 одним байтом, с ними это работает, но все равно, не надо использовать эти функции — это слишком ненадежно и легко сделать ошибку. Вывод: используй `mb_*` функции. Не используй доступ к строке как к массиву. В регулярных выражениях используй флаг `u` (он говорит что исплоьзуется utf-8 а не однобайтовая кодировка). Некоторые строковые функции без префикса mb тем не менее корректно работают с utf-8 и их можно использовать. Вот они: `strtr` (если передавать массив), `str_replace`, `str_repeat`, `explode`, `addslashes`, `trim`. -
codedokode revised this gist
Nov 16, 2014 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ Некоторые функции PHP (`strlen`, `substr`, а также обращение к строке как к массиву: `$str[0]`) не работают с многобайтовыми кодировками (вроде utf-8). В utf-8 1 символ закодирован с помощью от 1 до 6 байтов, а эти функции думают, что 1 буква всегда кодируется одним байтом. По этой причине они ломают символы, в результате получаются битые символы и ничего не работает. Потому вместо них надо использовать mb_ функции например `mb_strlen`, `mb_substr`. Вместо доступа к строке как к массиву надо использовать `mb_substr`. Если тебе интересно, почему эти функции поддерживают только однобайтные кодировки, а не многобайтные, то причина в том, что они очень старые и написаны в то время (лет 40 назад) когда utf-8 и многобайтных кодировок еще не было. -
codedokode revised this gist
Oct 10, 2014 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,7 @@ Некоторые функции PHP (`strlen`, `substr`, а также обращение к строке как к массиву: `$str[0]`) не работают с многобайтовыми кодировками (вроде utf-8). В utf-8 1 символ закодирован с помощью от 1 до 6 байтов, а эти функции думают, что 1 буква вегда кодируется одним байтом. По этой причине они ломают символы, в результате получаются битые символы и ничего не работает. Потому вместо них надо использовать mb_ функции например `mb_strlen`, `mb_substr`. Вместо доступа к строке как к массиву надо использовать `mb_substr`. Если тебе интересно, почему эти функции поддерживают только однобайтные кодировки, а не многобайтные, то причина в том, что они очень старые и написаны в то время (лет 40 назад) когда utf-8 и многобайтных кодировок еще не было. Давай разберем пример. Допустим, у нас есть строка из русской буквы «щ» в кодирове utf-8. Попытаемся взять первую букву с помощью неправильной функции: // Внимание! это неправильный код, не пиши так! -
codedokode revised this gist
Oct 10, 2014 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -22,4 +22,4 @@ ## mbstring.func_overload В неоторых (неграмотных) учебниках ты можешь увидеть совет включить опцию `mbstring.func_overload` (подробнее про нее: http://php.net/manual/ru/mbstring.overload.php ). Ни в коем случае так не делай, так как это изначально неправильно спроектированная опция. Она не решает проблему, для которой задумывалась (включить в старом приложении использующем функции вроде `strlen` поддержку utf-8), а лишь создает путаницу. Например, при ее включении `strlen` заменяется на поддерживающую utf-8 `mb_strlen`, но `ucfirst` ни на что не заменяется и не работает. -
codedokode revised this gist
Oct 10, 2014 . 1 changed file with 4 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -19,3 +19,7 @@ Некоторые строковые функции без префикса mb тем не менее корректно работают с utf-8 и их можно использовать. Вот они: `strtr` (если передавать массив), `str_replace`, `str_repeat`, `explode`, `addslashes`, `trim`. **Не** работают с utf-8: `strrev`, `strlen`, `substr`, `strpos`, `ucfirst`, `wordwrap` и большинство других строковых функций. ## mbstring.func_overload В неоторых (неграмотных) учебниках ты можешь увидеть совет включить опцию mbstring.fun_overload (подробнее про нее: http://php.net/manual/ru/mbstring.overload.php ). Ни в коем случае так не делай, так как это изначально неправильно спроектированная опция. Она не решает проблему, для которой задумывалась (включить в старом приложении использующем функции вроде `strlen` поддержку utf-8), а лишь создает путаницу. Например, при ее включении `strlen` заменяется на поддерживающую utf-8 `mb_strlen`, но `ucfirst` ни на что не заменяется и не работает. -
codedokode created this gist
Oct 8, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,21 @@ Некоторые функции PHP (`strlen`, `substr`, а также обращение к строке как к массиву: `$str[0]`) не работают с многобайтовыми кодировками (вроде utf-8). В utf-8 1 символ закодирован с помощью от 1 до 6 байтов, а эти функции думают, что 1 буква вегда кодируется одним байтом. По этой причине они ломают символы, в результате получаются битые символы и ничего не работает. Потому вместо них надо использовать mb_ функции например `mb_strlen`, `mb_substr`. Вместо доступа к строке как к массиву надо использовать `mb_substr`. Давай разберем пример. Допустим, у нас есть строка из русской буквы «щ» в кодирове utf-8. Попытаемся взять первую букву с помощью неправильной функции: // Внимание! это неправильный код, не пиши так! $s = "щ"; $x = substr($s, 0, 1); Буква «щ» кодируется в utf-8 как 2 байта: `209 137` (я взял информацию тут: http://www.utf8-chartable.de/unicode-utf8-table.pl?start=1024&utf8=dec ). substr отрезает от строки не первую букву, а первый **байт**. Это значит, что в $x он положит 1 байт с кодом `209`. В utf-8 это неверная последовательность, она не соответвует никакому символу (так как после `209` обязательно должно идти второе число). Ideone может вообще отказаться что-то отображать, встретив такой код. То же самое, когда ты обращаешься к строке как к массиву: `$s[0]`. Эта команда берет не первую букву, а только первый байт строки. Естественно, такая программа не будет работать. Функция `strlen` считает число байт (не букв) в строке. То есть в данном случае `strlen($s)` вернет нам 2. Латинница и цифры кодируются в utf-8 одним байтом, с ними это работает, но все равно, не надо использовать эти функции — это слишком ненадежно и легко сделать ошибку. Вывод: используй `mb_*` функции. Не исплоьзуй доступ к строке как к массиву. В регулярных выражениях используй флаг `u` (он говорит что исплоьзуется utf-8 а не однобайтовая кодировка). Некоторые строковые функции без префикса mb тем не менее корректно работают с utf-8 и их можно использовать. Вот они: `strtr` (если передавать массив), `str_replace`, `str_repeat`, `explode`, `addslashes`, `trim`. **Не** работают с utf-8: `strrev`, `strlen`, `substr`, `strpos`, `ucfirst`, `wordwrap` и большинство других строковых функций.