За последние 24 часа нас посетили 18595 программистов и 1705 роботов. Сейчас ищут 707 программистов ...

mb_strtolower, stripos и др. неработают с русскими символами

Тема в разделе "Прочие вопросы по PHP", создана пользователем mirra88, 25 апр 2013.

  1. mirra88

    mirra88 Новичок

    С нами с:
    25 апр 2013
    Сообщения:
    10
    Симпатии:
    0
    Уважаемые форумчане, доброго времени суток. Проблема проявилась таким образом.
    Когда я ввожу в код php строки, то они выводятся на экран нормально, но стоит обработать их функциями mb_strtolower, strtolower, stripos и некоторыми другими и строки сразу же превращаются в вопросы. Например если я введу:
    Код (Text):
    1. $A="мяч";
    2. echo $B="Наш мячик очень оригинальный!";
    то $B в таком же виде, как я ввела и будет отображена на экране. Но уже попытка преобразовать строку к нижнему регистру:
    Код (Text):
    1. echo $loveTextB= mb_strtolower($B);
    приведёт к тому, что на экране $loveTextB отобразится вот так: ��� ����� ����� ������������!
    В итоге результат работы функций непредсказуем. Например, попытка найти первую позиции вхождения в $B подстроки $A:
    Код (Text):
    1. echo $pos=stripos($loveTextB, $loveTextA);
    или
    Код (Text):
    1. echo $pos=stripos($B, $A);
    приведёт к выводу числа 7, что абсолютно не соответствует действительности. И я подозреваю, что это из-за этой вот петрушки с кодировками. Потому что если я перехожу на английский регистр, то всё становится нормально. И перевод к нижнему регистру строку не меняет и номера позиций правильно выдаются.

    Тестирую на Denver, PHP Version 5.2.12. В настройках сервера стоит:
    Код (Text):
    1. character_set_client    utf8
    2. character_set_connection    utf8
    3. character_set_database  cp1251
    4. character_set_filesystem    binary
    5. character_set_results   utf8
    6. character_set_server    cp1251
    7. character_set_system    utf8
    Кодировка в разделе для мета тегов указана:
    Код (Text):
    1. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> ;
    В cкрипте настроек php прописаны команды:
    Код (Text):
    1. header('Content-Type: text/html; charset= utf-8');
    и
    Код (Text):
    1. setlocale(LC_ALL, 'Russian_Russia.65001');
    Подключен файл .htaccess со строкой:
    Код (Text):
    1. AddDefaultCharset utf-8
    Никто не знает почему некоторые функции php так реагируют на русскую кодировку и как этот момент можно исправить или обойти?
     
  2. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Валерий Е нравится это.
  3. mirra88

    mirra88 Новичок

    С нами с:
    25 апр 2013
    Сообщения:
    10
    Симпатии:
    0
    Re: mb_strtolower, stripos и др. неработают с русскими симво

    Спасибо, действительно, когда я указала вот так:
    Код (Text):
    1. echo $loveTextB= mb_strtolower($B,'utf-8');
    то преобразованные строки стали отображаться правильно.

    А как можно указать в какой кодировке работать другим функциям? Например stripos как выдавала, что "Мяч" входит в строку начиная с седьмой позиции, так и выдаёт. А стоит заменить всё на английские символы и номер позиции выдаётся правильно: четвёртая.
     
  4. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Re: mb_strtolower, stripos и др. неработают с русскими симво

    mb_stripos?
     
  5. mirra88

    mirra88 Новичок

    С нами с:
    25 апр 2013
    Сообщения:
    10
    Симпатии:
    0
    Re: mb_strtolower, stripos и др. неработают с русскими симво

    А вот mb_stripos, в отличие от stripos, выдала четвёртую позицию! Спасибо большое! Теперь я, кажется, поняла в каком направлении идти. Надо будет посмотреть, чем эти mb_stripos, mb_strtolower и пр. отличаются от stripos, strtolower ну и т. д.
     
  6. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Re: mb_strtolower, stripos и др. неработают с русскими симво

    Тем что вы работаете с многобайтными строками.
    По этому вы случайно можете отрезать меньше символов, чем сделают это mb_* функции...

    Тут же все написано:
    php.net/manual/ru/book.mbstring.php

    Почему вы начинаете программировать не читая мануал? Это очень глупо.
     
  7. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Re: mb_strtolower, stripos и др. неработают с русскими симво

    а я вам прям щас могу объяснить - они работают с мультибайтными строками.
    есть скажем кодировка cp1251 - она однобайтная, первые 128 символов жестко соответствуют ASCII и содержат латиницу, нумералы, управляющие символы и тп. а в следующих 127 уже встречается кириллица.
    юникод utf-8 - двухбайтная кодировка, для латиницы используется один байт и полностью соответствует любой другой кодировке и ASCII. а вот для прочих языков используется два байта.
    строка 'qzбж' (4 символа) в кп1251 будет занимать 4 байта - два латинских и два кириллических. в утф-8 - 6 байт - 2 латиница и 2*2 кириллических.
    когда вы применяете однобайтную функцию (stripos) она работает с 6 байтами как с 6 символами, а когда мультибайтную (mb_stripos) она учитывает что некоторые символы мультибайтны и работает с 6 байтами как с 4 символами.

    получилось объяснить?(
     
  8. mirra88

    mirra88 Новичок

    С нами с:
    25 апр 2013
    Сообщения:
    10
    Симпатии:
    0
    Re: mb_strtolower, stripos и др. неработают с русскими симво

    Да, Ganzal, всё понятно, спасибо большое! И спасибо всем, кто мне помог!
     
  9. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    Re: mb_strtolower, stripos и др. неработают с русскими симво

    mb_internal_encoding() поможет указать настройки действующие на все мульбайтовые функции
     
  10. mirra88

    mirra88 Новичок

    С нами с:
    25 апр 2013
    Сообщения:
    10
    Симпатии:
    0
    Re: mb_strtolower, stripos и др. неработают с русскими симво

    Действительно.. Сейчас попробовала из рнр-скрипта убрать эту строку:
    Код (Text):
    1. mb_internal_encoding("UTF-8");
    которая по счастью у меня была. И ... сразу даже и mb_stripos стала работать неправильно! Спасибо. Тут получается надо не одно, а несколько условий не забывать.
     
  11. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Официальный сайт является php.net
    Вы наверное даже не знаете, где смотреть))
    Код (PHP):
    1. string mb_strtolower ( string $str [, string $encoding = mb_internal_encoding() ] ) 
    Заметьте, что пишется в [, string $encoding = mb_internal_encoding() ]
    В квадратных скобках свойства (переменные) не обязательные но по умолчанию, то есть можно не указывать.
    Все, что находится в круглых скобках является прототипом метода (функции).

    Код (PHP):
    1. echo $B="Наш мячик очень оригинальный!"; 
    А зачем так писать? =(
     
  12. mirra88

    mirra88 Новичок

    С нами с:
    25 апр 2013
    Сообщения:
    10
    Симпатии:
    0
    Re: mb_strtolower, stripos и др. неработают с русскими симво

    Your, я бы ответила на Ваш вопрос, но я не могу его понять... А как тогда надо писать, если не так?
     
  13. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Зачем вы пишите в операторе вывода переменную и присваиваете ей значение?) Это как-то глупо, так никто не пишет)
    Код (PHP):
    1. echo"Наш мячик очень оригинальный!"; 
     
  14. mirra88

    mirra88 Новичок

    С нами с:
    25 апр 2013
    Сообщения:
    10
    Симпатии:
    0
    Re: mb_strtolower, stripos и др. неработают с русскими симво

    Поняла. Я вообще-то так тоже не пишу. И цель программки была не вывести переменную, а организовать поиск. Но как иначе я могла наглядно выделить проблему на форуме? Привести большой код с ненужными классами и функциями?
    Чтобы показать проблему я просто максимально упростила выдаваемый на форум кусочек кода.
     
  15. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Re: mb_strtolower, stripos и др. неработают с русскими симво

    :D
    Ну наверно это я так написал :)