Заметки о PHP: изменение кодировки массива

Иногда бывает так, что мы получаем массив, в котором элементы имеют кодировку, которая нам без надобности. Необходимо преобразовать все элементы массива в нужную нам кодировку. Когда массив одномерный — это не составляет труда. Но когда мы имеем многомерный массив, могут возникнуть трудности — нам ведь надо опускаться на неопределенную глубину. Следующая маленькая функция решит эту тривиальную задачу:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function iconvArray($inputArray,$newEncoding){
  $outputArray=array();
    if ($newEncoding!=''){
      if (!empty($inputArray)){
        foreach ($inputArray as $element){
          if (!is_array($element)){
            $element=iconv(mb_detect_encoding($element),
              $newEncoding,$element);
          } else {
            $element=iconvArray($element);
          }
          $outputArray[]=$element;
        }
      }
    }
  return $outputArray;
}

Просто и… рекурсивно 😉

Похожие статьи:

Запись опубликована в рубрике php с тэгами , , , , , , . Создать закладку на запись. Оставить комментарий или trackback: Trackback URL.

18 комментариев

  1. Артём
    Опубликован 26 ноября 2009 в 22:35 | Прямая ссылка

    Позволю себе немного отредактировать (справить) твою функцию:

    function iconvArray ($inputArray,$newEncoding){

    $outputArray=array ();

    if ($newEncoding!=''){

    if (!empty ($inputArray)){

    foreach ($inputArray as $key => $element){

    if (!is_array ($element)){

    $element=iconv ($newEncoding,mb_detect_encoding ($element),$element);

    } else {

    $element=$this->iconvArray ($element, $newEncoding);

    }

    $outputArray[$key]=$element;

    }

    }

    }

    return $outputArray;

    }

    • Опубликован 28 ноября 2013 в 7:43 | Прямая ссылка

      В строке $element=iconv ($newEncoding,mb_detect_encoding ($element),$element); надо поменять местами старую и новую кодировку

      $element=iconv (mb_detect_encoding ($element),$newEncoding,$element);

  2. Опубликован 27 ноября 2009 в 9:11 | Прямая ссылка

    Согласен, моя функция была написана для простых, но не ассоциативных массивов. Мне уже довелось ее переписать, когда я при разработке получал ассоциативный массив. Твою функцию, кстати, можно дополнить изменением кодировки в ключе, т.к. в ассоциативных массивах можно задавать ключи, состоящие из национальных символов (н-р, кириллицы), и, конечно же, рано или поздно, придется столкнуться с такими массивами.

    • mosesfender
      Опубликован 8 июля 2011 в 17:02 | Прямая ссылка

      Смутно представляю себе человека, который станет ключи в массивах писать буквами отличными от общепринятой латиницы, и цифрами непохожими на арабские. Разве что какой-то нечеловек, выносящий мозг своими потугами в MSAccess.

  3. Артём
    Опубликован 27 ноября 2009 в 20:00 | Прямая ссылка

    Там есть еще пару чисто технических ошибочек, в «iconv» и рекурсивном вызове функции. А вообще ты прав что ключики нужно тоже декодировать.

    Peace.

  4. Михаил
    Опубликован 23 марта 2011 в 10:36 | Прямая ссылка

    А как насчет использования указателей? Заместо генерации нового массива. Вот пример моей функции

    function Decode (&$sVal)

    {

    if (is_array ($sVal))

    {

    foreach ($sVal as &$bVal)

    {

    CAllSplitTest::Decode (&$bVal);

    }

    }

    else

    {

    $sVal = iconv («utf-8»,LANG_CHARSET,$sVal);

    }

    }

    • Опубликован 24 марта 2011 в 11:09 | Прямая ссылка

      Один момент — utf-8 здесь не универсально. Причина этому — если данные приходят извне, то они могут быть в совершенно произвольной кодировке. Также, стоит учитывать и то, что кодировка базы данных, из которой приходят данные, тоже может смениться.

      Я бы сделал здесь сам себе ещё одно замечание 🙂 — mb_detect_encoding (), которую я использую в статье, возвращает значение ASCII, если в качестве параметра ей отправлена строка в какой-нибудь однобайтовой кодировке, типа Windows-1251. Такое поведение mb_detect_encoding () стоит обрабатывать дополнительно.

  5. Михаил
    Опубликован 24 марта 2011 в 12:20 | Прямая ссылка

    Да нет, разумеется насчет «utf-8» не универсально =) я скинул пример именно своей функции, а у меня там всё чисто на utf-8, мне текущее определение ни к чему. Мой пример был лишь для наглядности работы с указателями на массивы, дабы не забивать лишнюю память, создавая новые массивы. Особенно, если работаешь с большими дампами.

  6. mosesfender
    Опубликован 8 июля 2011 в 14:55 | Прямая ссылка

    Стесняюсь спросить, а что означает сие $this->iconvArray ($element, $newEncoding); в девятой строке? Откуда взялся некий объект $this? Или я чего-то не вижу, что видят все остальные?

    • Опубликован 8 июля 2011 в 18:45 | Прямая ссылка

      Не надо стесняться ;). Это я забыл подправить функцию, когда копировал её из своего класса 🙂 . Спасибо за наводку, я поправил код.

  7. mosesfender
    Опубликован 8 июля 2011 в 15:34 | Прямая ссылка

    Кстати также замечу, что в случае перекодирования из cp1251 mb_detect_encoding абсолютно бесполезна, потому что всегда вернёт UTF-8, что сводит всю эту функцию к состоянию полной ненужности. А учитывая, что русскоязычных граждан с русскоязычными сайтами интересует прежде всего перекодировка из cp1251 в UTF-8 (например, чтобы получить JSON для AJAX-запросов), то это всё действительно не нужно. Проще знать входящую и исходящую кодировки и тупо так и писать: iconvArray («cp1251», «UTF-8», $_POST);

    • Опубликован 8 июля 2011 в 18:53 | Прямая ссылка

      mb_detect_encoding над cp1251 вернет в качестве результата ASCII, так что здесь тоже можно сориентироваться — добавить условие. В любом случае, mb_ функции для однобайтовых кодировок не предназначены.

      • mosesfender
        Опубликован 8 июля 2011 в 19:15 | Прямая ссылка

        В том-то и потеха, что префикс «mb» означает «мультибайт», и всякие однобайтные кодировки просто игнорирует.

        Специально попробовал: ASCII возвращает если нет букв. С буквами возвращает непременно UTF-8.

        • Опубликован 9 июля 2011 в 0:25 | Прямая ссылка

          Верно. Если требуется преобразовывать cp1251 моей функцией, то наиболее простым решением будет, конечно, предложенное тобой.

  8. Опубликован 24 января 2012 в 17:05 | Прямая ссылка

    Хорошая функция, свое дело делает. А вот если в исходном массиве в начале стоит буква Ё, ему сносит крышу, как полечить, уважаемые?

    Вот пример такого массива:

    (

    [0] => Ёмкость для воды

    )

  9. Опубликован 24 января 2012 в 17:31 | Прямая ссылка

    Полечил, явно указал кодировку $element=iconv ($newEncoding, «UTF-8»,$element);

    • Опубликован 24 января 2012 в 18:20 | Прямая ссылка

      Как раз писал комментарий в ответ на твой вопрос 🙂 . Можно попробовать ещё вот это phpclub.ru/faq/CharsetDetection для определения кодировки. Правда я не пользовался этими скриптами, не могу сказать насколько они корректно определяют кириллицу.

Оставить комментарий

Ваш e-mail никогда не будет опубликован или передан третьим лицам. Обязательные поля отмечены *

*
*