Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Проблема с функцией strlen()

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: Проблема с функцией strlen и строкой русскими буквами в utf-8
Haron
Отправлено: 05 Апреля, 2011 - 18:44:40
Post Id



Частый гость


Покинул форум
Сообщений всего: 197
Дата рег-ции: Июнь 2010  
Откуда: Оттуда


Помог: 5 раз(а)




Итак, передаю я функции strlen() русскую строку (естественно urldecode) в кодировке utf-8 и начинаются интересные вещи!
Оказывается, что длина слова "ты" - 4 символа, слова "член" - 8 символов, тогда как длина слова "ас" - 44(!) символа.

Парни, что делать? Есть ли способ правильно определить число букв в utf-8 русском слове?

(Отредактировано автором: 05 Апреля, 2011 - 18:45:15)



-----
И чё?
 
 Top
valenok Модератор
Отправлено: 05 Апреля, 2011 - 19:05:51
Post Id



Здесь могла бы быть ваша реклама


Покинул форум
Сообщений всего: 4574
Дата рег-ции: Июль 2006  
Откуда: Israel


Помог: 3 раз(а)






-----
Truly yours, Sasha.
 
My status
 Top
Haron
Отправлено: 05 Апреля, 2011 - 19:17:30
Post Id



Частый гость


Покинул форум
Сообщений всего: 197
Дата рег-ции: Июнь 2010  
Откуда: Оттуда


Помог: 5 раз(а)




valenok пишет:


Не канает Недовольство, огорчение
Результаты работы multibyte-функции:

Длина строки из одной (любой) русской буквы равна 11
Длина слова "вся" - 33

Да и ещё...
В поисках решения проблемы и независимости от multibyte расширения -, был придуман такой вот костыль:
PHP:
скопировать код в буфер обмена
  1. function ce_strlen($str) {
  2.         $str = utf8_decode($str);
  3.         $k = 0;
  4.         while(@$str{$k}) {
  5.                 $arr[$k] = $str{$k};
  6.                 $k++;
  7.         }
  8.         return count($arr);
  9. }


Выдаёт те же печальные результаты на некоторых словах, что и mb_strlen();

(Отредактировано автором: 05 Апреля, 2011 - 19:27:41)



-----
И чё?
 
 Top
OrmaJever Модератор
Отправлено: 05 Апреля, 2011 - 19:31:42
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




Haron пишет:
Не канает

если написали значит это работает, просто вы что-то не так делаете!


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
valenok Модератор
Отправлено: 05 Апреля, 2011 - 19:36:52
Post Id



Здесь могла бы быть ваша реклама


Покинул форум
Сообщений всего: 4574
Дата рег-ции: Июль 2006  
Откуда: Israel


Помог: 3 раз(а)




Дайте угадаю. Длинна слова из 10 букв у вас 1010 ?


-----
Truly yours, Sasha.
 
My status
 Top
DeepVarvar Супермодератор
Отправлено: 05 Апреля, 2011 - 19:39:07
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Haron строка откуда появляется? Из файла? $_GET/POST? Из базы?
 
 Top
Haron
Отправлено: 05 Апреля, 2011 - 19:47:31
Post Id



Частый гость


Покинул форум
Сообщений всего: 197
Дата рег-ции: Июнь 2010  
Откуда: Оттуда


Помог: 5 раз(а)




Цитата:
Дайте угадаю. Длинна слова из 10 букв у вас 1010 ?

Не угадали, FAIL

Цитата:
Если написали значит это работает, просто вы что-то не так делаете!

А если напишут что йа редиско, йа редиско?

Цитата:
Haron строка откуда появляется? Из файла? $_GET/POST? Из базы?

Из массива $_GET.

Правда, $_GET - сразу обрабатывается функцией очистки от "вредных" вложений:
PHP:
скопировать код в буфер обмена
  1. function __data_clean($input)
  2.         {
  3.                 $utf8 = (preg_match("/^([\x09\x0A\x0D\x20-\x7E]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})*$/", $input)) ? true : false;
  4.                 if ($utf8)
  5.                 {
  6.                         $input = urldecode($input);    
  7.                 }
  8.                 else
  9.                 {
  10.                         $input = iconv('cp1251', 'UTF-8', (urldecode($input)));
  11.                 }
  12.                 $input = htmlentities($input, ENT_QUOTES, 'UTF-8');
  13.                 $input = strip_tags($input);
  14.                 $input = str_replace ("\n"," ", $input);
  15.                 $input = str_replace ("\r","", $input);
  16.                 return $input;
  17.         }


Однако, на проблему она никак не влияет (Проблема сохраняется если данные идут мимо функции). Задача этой функции - получить на выходе безопасную строку unicode и работает она корректно.


-----
И чё?
 
 Top
DeepVarvar Супермодератор
Отправлено: 05 Апреля, 2011 - 19:52:50
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Заголовки при отдаче страницы (с которой потом этот ГЕТ прилетает) отправляете?
PHP:
скопировать код в буфер обмена
  1. header('Content-Type: text/html; charset=utf-8');
 
 Top
Haron
Отправлено: 05 Апреля, 2011 - 19:57:45
Post Id



Частый гость


Покинул форум
Сообщений всего: 197
Дата рег-ции: Июнь 2010  
Откуда: Оттуда


Помог: 5 раз(а)




DeepVarvar пишет:
Заголовки при отдаче страницы (с которой потом этот ГЕТ прилетает) отправляете?
PHP:
скопировать код в буфер обмена
  1. header('Content-Type: text/html; charset=utf-8');


Конечно. Более того, все файлы проекта, база данных и типы записей - utf-8.
Файлы без BOM


-----
И чё?
 
 Top
valenok Модератор
Отправлено: 05 Апреля, 2011 - 19:58:58
Post Id



Здесь могла бы быть ваша реклама


Покинул форум
Сообщений всего: 4574
Дата рег-ции: Июль 2006  
Откуда: Israel


Помог: 3 раз(а)




создайте отедльный файл и выполните в нем команды
PHP:
скопировать код в буфер обмена
  1.  
  2. echo mb_strlen('член', 'UTF-8'), ', ', mb_strlen($_GET['x'], 'UTF-8');
  3.  


-----
Truly yours, Sasha.
 
My status
 Top
DeepVarvar Супермодератор
Отправлено: 05 Апреля, 2011 - 20:09:37
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




valenok пишет:
и выполните

У меня все прошло удачно. (nginx,phpFCGI)
 
 Top
Haron
Отправлено: 05 Апреля, 2011 - 20:17:56
Post Id



Частый гость


Покинул форум
Сообщений всего: 197
Дата рег-ции: Июнь 2010  
Откуда: Оттуда


Помог: 5 раз(а)




Нашёл ошибку. Прошу прощения, всё нормально Улыбка. Зря гнал.


-----
И чё?
 
 Top
DeepVarvar Супермодератор
Отправлено: 05 Апреля, 2011 - 20:22:53
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Haron а что было то?
 
 Top
Haron
Отправлено: 05 Апреля, 2011 - 20:28:03
Post Id



Частый гость


Покинул форум
Сообщений всего: 197
Дата рег-ции: Июнь 2010  
Откуда: Оттуда


Помог: 5 раз(а)




Два прогона вместо одного (в некоторых случаях) в цикле с echo.
Так что товарищ Valenok оказался таки прав Улыбка Приношу ему извинения.


-----
И чё?
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Программирование на PHP »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB