Ответ простой: да, чтобы не было граблей всё должно быть в utf8. utf8_general_ci - это collate в mysql для utf8
Ответ правильный:
Doox911 пишет:
Т.е. корректно будет работать если html, скрипты и база в UTF-8?
Для PCRE будет уже достаточно если поисковый паттерн и текст в котором ищем в UTF8, всё остальное может быть в других кодировках.
В рамках своего проекта чтобы не иметь головной боли с кодировками - да, использовать utf8. При необходимости в общении с внешними системами на каких-то других кодировках - перекодируйте данные через iconv или mb_convert_encoding сразу при приёме данных.
Doox911 пишет:
UTF-8 и utf-8_general_ci одно и тоже?
Скорей всего речь о mysql и тогда правильный ответ будет на настоящее время - лишь частично.
utf8_general_ci - это правила сравнения и сортировки для utf8, данные для этого соответственно лежат в utf8. А дальше исторический казус:
Изначально utf8 был от 1 до 6 байт на символ, но в mysql решили что им хватит 3 байт и тихо ломали не влезающие в 3 байта символы.
Потом utf8 стандарт урезали до 4 байт максимум.
Потом в Mysql 5.5.(что-то) сделали грубый костыль - кодировку названную utf8mb4, который в отличии от исторически дефектного в mysql utf8 умеет в 4 байт на символ и соответствует стандарту. В будущем в mysql алиас кодировки utf8 планируют переключить с utf8mb3 на utf8mb4. Но до тех пор - utf8 как стандарт и utf8 как кодировка в mysql совпадают только на 75%.
Спасибо (уже и кликнул). Очень подробно и понятно. Теперь есть понимание. В целом в двух проектах я использую везде только utf8. Получается конвертировать мне необходимо только если я например использую стороннее api или работаю с пользовательским файлом?
Это в принципе невозможно.
Если кодировка текста не известна заранее - то её можно пытаться только угадать. Потому что байты-то везде одни и те же, а кодировок - суть таблиц преобразования произвольного байта в представление на экране - огромное множество наплодили.
Флаг u подписан в мануале и маппится в коде в PCRE_UTF8, т.е. регулярка будет работать исходя из предположения, что и паттерн и текст переданы в utf8
Т.е. корректно будет работать если html, скрипты и база в UTF-8? UTF-8 и utf-8_general_ci одно и тоже?
Т.е. получается при добавлении модификатора u регулярка сама поймёт в какой кодировке сравнивать? Или будет сравнивать исходя из того что в скрипте предполагается, что символ пришел в кодировке utf8 и скрипт сохранён в той же кодировке?
Не могу настроить виртуальные хосты nginx на Ubuntu 18. Настроил php. Сайт написан на модели MVC. На сторонних серверах типо reg.ru всё работает. На моём сервере обычные php фалы работают. Работает phpmyadmin. А вот сайт (другой адрес) не хочет. В логах nginx пусто (/var/log/nginx) - ошибок нет. Устанавливал пакет nginx full вроде. В файле hosts прописал ip:
Вроде разобрался. В каждом проекте создаём свой файл composer.json. Из терминала или командной строки переходим в папку проекта. И в нём запускаем(локально установлен):
Это байты в распространённой hex записи.
Пользуясь какой-нибудь таблицей кодирования можно попробовать представить в виде символов.
Для utf8 это будет один символ т, для cp1251 - строка из двух символов: "С‚", строка "Ń‚" в cp1250 и так далее по куче разных кодировок с различным эффектом.
Doox911 пишет:
Не совсем понял что за d0 b0:
Тоже байты в hex виде. Без \x и с пробелами обычно читается легче человеком.
Зависит от того что считать корректным. С точки зрения механики - все результаты корректны.
Мелкий пишет:
var_dump(preg_match("~[абв]~", "где"));
Обозначу для краткости символы:
а состоит из байтов 1 и 2 (реально d0 b0)
б - 1 и 3 (d0 b1)
в - 1 и 4 (d0 b2)
г - 1 и 5 (d0 b3)
д - 1 и 6 (d0 b4)
е - 1 и 7 (d0 b5)
да, d0 у них у всех реально совпадает. В итоге получаем без модификатора u выражение:
Именно так, сравниваем байты, в символьной маске не 3 объекта для сравнения, а 6, из них 3 одинаковые. Есть у нас байт 1? Есть, потому и получаем совпадение.
С модификатором u рассматриваем именно символы, потому в символьной маске будет только 3 объекта. И соответственно отсутствие совпадения.
Doox911 пишет:
при перемене мест символов?
При перемене мест байт. Я специально воспользовался hex записью чтобы проиллюстрировать и дописал комментарий, что такая изменённая последовательность байт вообще недопустима в utf8.
С точки зрения механики - бесспорно).
Я что-то запутался.
\xd1\x82 - этo байты? Или символы? Я предполагаю, что это символы "," и "С".
Для UTF8 как представителя кодировки с переменной шириной символа в принципе нет возможности взять произвольный i-тый символ строки без просмотра всех символов от 0 до i, что ожидаемо даёт замедление алгоритма.
Поясню как раз на замечательном примере из другой вашей темы: http://forum.php.su/topic.php?fo...87399#1531887399
Ваш алгоритм некорректно обрабатывает символы utf8. Но сама идея байтового обхода исходной строки при этом корректна.
Пример armancho7777777 получит замедление потому что в принципе невозможно получать offset в mb_substr без полного просмотра этого самого offset. На каждой итерации цикла.
Корректно обходить кодировки переменной длины - это взять следующий байт строки, если это не полный символ кодировки - брать следующие байты. Когда собрали символ - сверять полученный символ с заданной символьной маской. Если есть совпадение, то берём следующий байт и собираем новый символ и проверяем уже его. Если не совпали - ура, выходим, под шаблон строка не подпадает. Именно так работает PCRE и вообще конечные автоматы регулярных выражений.
В возможность корректно обойти utf8 в userspace php и обогнать элементарную регулярку - я не верю. Проверять лениво, много граблей обходить надо. А производительность libpcre в PHP ещё и весьма непросто корректно проверять из-за кеша регулярок в нескромные 4096 штук. Ёпт, а там ещё и JIT включен уже может быть. Это без вариантов, по крайней мере пока для userspace не прикрутят JIT.
т.е. когда я беру символ и сравниваю именно как символ и знаю что символ в utf-8 php всё равно не понимает его код? Он всегда сравнивает по битно? И что значит utf-8, что резиновая? utf-16 2 я так понимаю строго 2 байта = 16 бит.
Становится очевидно, почему ^т$ и ^[т]$ ведут себя различно в зависимости от u?
Сравниваем байты или символы. Маленькая разница, небольшие но важные изменения. (Добавление)
Ну и маленький выдуманный пример, проверим, что в строке есть хотя бы одна буква а, б или в:
А юникод потому что некоторые русские символы не влезли?
u - потому что работаете с многобайтовой кодировкой. Но есть случаи, в которых при работе с юникодом, модификатор u можно не указывать - обычно это когда в шаблоне искомое слово прописано как есть. Сравните эти два примера: