Переход на UTF-8 и нюансы с mysql

Духовность™

Продвинутый новичок
а вот это поведение мне совсем не понятно:

PHP:
mb_internal_encoding('UTF-8');

$s = 'вася';
for ($i=0; $i<mb_strlen($s); $i++) echo $s[$i]; // "ва"
for ($i=0; $i<strlen($s); $i++) echo $s[$i]; // "вася"
почему не работает с mb_strlen и работает со strlen?
точнее мне понятно... но как то я не привык так работать...
 

Вурдалак

Продвинутый новичок
Это тебе не ООП, тут думать надо. $s[$i] это всё равно что substr($s, $i, 1). Если тебе нужен один символ, что используй mb_substr().
 

fixxxer

К.О.
Партнер клуба
Не выйдет никакая 6-я версия, методика "расставим на каждой второй строке кода if" себя не оправдала, актуальным и последним является код транка 5.4.


mbsting overload это простой хак, подменяющий строковые функции, ровно того же можно достичь runkit-ом. Строки так и остаются простым набором байтиков.
 

caballero

Новичок
Как БД хранит данные не имеет значения. Могут быть заданы дефолтные кодировки столбца, таблицы, БД, сервера или клиента (который по дефолту берет из системмы). Вопрос кодировок - еще тот гемор.
Нужно просто указать SET NAMES (UTF8 если нет спец требований) в какой кодировке БД должна принимать и отдавать данные - остальное ее забота
Ну и еще иногда полезен collation для правильной сортировки нелатиничных строк
 

caballero

Новичок
Можно бы и просто PHP обновить, там кодировка по умолчанию исправлена.
Нет, UTF8 не стала внутренней кодировкой - это пока вызывает больше проблем (для компилятора и испольняемой среды PHP) чем пользы.
 

Absinthe

жожо
ровно того же можно достичь runkit-ом
Поподробнее, пожалуйста. Я знаю всего лишь 1 способ перегрузки функций(замена указателей в таблице).

в каком именно php и как исправлена?
5.4: изменили кодировку по умолчанию, и теперь последний параметр mb_* функций не нужен.

Нет, UTF8 не стала внутренней кодировкой - это пока вызывает больше проблем (для компилятора и испольняемой среды PHP) чем пользы.
Я где-то говорил про внутренние кодировки? Я сказал, что последнее значение функции имеет вариант по умолчанию(function($var1, $var2=$default) {), который и изменили.
 

Духовность™

Продвинутый новичок
а вот это поведение мне совсем не понятно:

PHP:
mb_internal_encoding('UTF-8');

$s = 'вася';
for ($i=0; $i<mb_strlen($s); $i++) echo $s[$i]; // "ва"
for ($i=0; $i<strlen($s); $i++) echo $s[$i]; // "вася"
почему не работает с mb_strlen и работает со strlen?
точнее мне понятно... но как то я не привык так работать...
И всё равно, я не понимаю. Чисто по логике. По восприятию. По мышлению. У меня реально краш мозга происходит.

Функция mb_strlen типа сделана для работы с mb строками.
И возвращает "длину строки". В чем? Очевидно, кол-во символов, а не байт, ибо mb_strlen('вася') дает 4, а не 8 как я ожидаю.
Объясните, не пойму. И как теперь посимвольно пройтись по строке, если нужно что-то парсить, типа так:

PHP:
$s = 'вася';
for ($i=0; $i<strlen($s); $i++) {
    if ($s[$i] == 'а') echo 'буква а найдена в слове!';
}
 

Духовность™

Продвинутый новичок
короче, правильно ли я понимаю, что для mb проекта всегда нужно использовать mb_* функции?
 

Ярослав

Новичок
короче, правильно ли я понимаю, что для mb проекта всегда нужно использовать mb_* функции?
нет, если к примеру мы знаем что там 100% ascii то нахрена нам mb

Так. А как поменять данные в таблицах, сделав их UTF?
<<<Сообщения: 4 879
Жесть...
 

Royal Flash

-=MaestrO=-
Функция mb_strlen типа сделана для работы с mb строками.
И возвращает "длину строки". В чем? Очевидно, кол-во символов, а не байт, ибо mb_strlen('вася') дает 4, а не 8 как я ожидаю.
Объясните, не пойму. И как теперь посимвольно пройтись по строке, если нужно что-то парсить, типа так:
Все очень просто - воспользуйтесь кодом ниже, и поэкспериментируйте: закомментируйте/раскомментируйте mb_internal_encoding и напишите "вася" в utf-8 кодировке, и например, в win-1251 - все сразу станет яснее. Еще большую ясность Вам внесет документация на русском языке по mb_strlen() - там четко написано: "Возвращает количество символов в строке (string) str, имеющих кодировку символов encoding. Многобайтный символ вычисляется как 1."

PHP:
<?php
mb_internal_encoding('UTF-8');
$s = 'вася';

echo 'mb_internal_encoding: '.mb_internal_encoding().';<br> strlen: '.strlen($s).';<br> mb_strlen: '.mb_strlen($s).'.';
?>
Возможно, кто-то поделится парсером, чтобы заменить все не MB функции во всех скриптах за 1 раз?
 

Sufir

Я не волшебник, я только учусь
Возможно, кто-то поделится парсером, чтобы заменить все не MB функции во всех скриптах за 1 раз?
Да, любая нормальная IDE может, мне кажется. По крайней мере NetBeans'ом я пути и имена классов заменял без проблем и довольно шустро.
 

Royal Flash

-=MaestrO=-
Не совсем то - есть много скриптов, разработанных под win-1251. Конвертировать данные - не проблема: iconv и все работает. Необходимо: изменить все preg_replace с диапазонами из русских букв - добавить u (это можно только вручную) и заменить все строковые функции (strtolower -> mb_strtolower и т.п.) на аналоги mb.
 

lagoff

Новичок
И всё равно, я не понимаю. Чисто по логике. По восприятию. По мышлению. У меня реально краш мозга происходит.

Функция mb_strlen типа сделана для работы с mb строками.
И возвращает "длину строки". В чем? Очевидно, кол-во символов, а не байт, ибо mb_strlen('вася') дает 4, а не 8 как я ожидаю.
Объясните, не пойму. И как теперь посимвольно пройтись по строке, если нужно что-то парсить, типа так:

PHP:
$s = 'вася';
for ($i=0; $i<strlen($s); $i++) {
    if ($s[$i] == 'а') echo 'буква а найдена в слове!';
}
Причина в том, как работает оператор [] cо строками. А судя по поведению работает он просто: считывает данные длиной 1 байт и смещением указанным в []. Т.е. он тупо не перегружается для мультибайтовых строк.
Отсюда и получается, что mb_strlen возвращает нам 4, и мы считываем только 4 байта, что равно двум символам.
А вот strlen возвращает 8 - вот вся строка и выводится.

И как теперь посимвольно пройтись по строке
Просто.
PHP:
$s = 'вася';
for ($i=0; $i<strlen($s); $i+=2) {
    if ($s[$i] . $s[$i+1] == 'а') echo 'буква а найдена в слове!';
}
 

Royal Flash

-=MaestrO=-
Да, любая нормальная IDE может, мне кажется. По крайней мере NetBeans'ом я пути и имена классов заменял без проблем и довольно шустро.
Вот установил себе Netbeans - рефакторинг, конечно, рулит :) Спасибо, что удержали от "изобретения" очередного велосипеда! А то мой старый добрый Zend 5 уже мягко говоря "немного" устарел.
 
Сверху