Переход на 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().
 
Не выйдет никакая 6-я версия, методика "расставим на каждой второй строке кода if" себя не оправдала, актуальным и последним является код транка 5.4.


mbsting overload это простой хак, подменяющий строковые функции, ровно того же можно достичь runkit-ом. Строки так и остаются простым набором байтиков.
 
Как БД хранит данные не имеет значения. Могут быть заданы дефолтные кодировки столбца, таблицы, БД, сервера или клиента (который по дефолту берет из системмы). Вопрос кодировок - еще тот гемор.
Нужно просто указать SET NAMES (UTF8 если нет спец требований) в какой кодировке БД должна принимать и отдавать данные - остальное ее забота
Ну и еще иногда полезен collation для правильной сортировки нелатиничных строк
 
Можно бы и просто PHP обновить, там кодировка по умолчанию исправлена.
Нет, UTF8 не стала внутренней кодировкой - это пока вызывает больше проблем (для компилятора и испольняемой среды PHP) чем пользы.
 
ровно того же можно достичь 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

Жесть...
 
Функция 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 раз?
 
Возможно, кто-то поделится парсером, чтобы заменить все не MB функции во всех скриптах за 1 раз?
Да, любая нормальная IDE может, мне кажется. По крайней мере NetBeans'ом я пути и имена классов заменял без проблем и довольно шустро.
 
Не совсем то - есть много скриптов, разработанных под win-1251. Конвертировать данные - не проблема: iconv и все работает. Необходимо: изменить все preg_replace с диапазонами из русских букв - добавить u (это можно только вручную) и заменить все строковые функции (strtolower -> mb_strtolower и т.п.) на аналоги mb.
 
И всё равно, я не понимаю. Чисто по логике. По восприятию. По мышлению. У меня реально краш мозга происходит.

Функция 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 'буква а найдена в слове!';
}
 
Да, любая нормальная IDE может, мне кажется. По крайней мере NetBeans'ом я пути и имена классов заменял без проблем и довольно шустро.
Вот установил себе Netbeans - рефакторинг, конечно, рулит :) Спасибо, что удержали от "изобретения" очередного велосипеда! А то мой старый добрый Zend 5 уже мягко говоря "немного" устарел.
 
Сверху