За последние 24 часа нас посетили 22502 программиста и 998 роботов. Сейчас ищут 679 программистов ...

Нужна помощь PHP обработка многомерного массива

Тема в разделе "PHP для новичков", создана пользователем New_neo, 28 фев 2017.

  1. New_neo

    New_neo Новичок

    С нами с:
    15 ноя 2015
    Сообщения:
    77
    Симпатии:
    3
    Нужна помощь PHP обработка многомерного массива. Есть функция которая обрабатывает один массив по регулярному выражению!
    Код (Text):
    1. if(preg_match_all("/\[d-(.*?)\|(.*?)\]/", $text, $temp)) {
    2.             $string = '';
    3.             foreach($temp[1] as $key => $item) {
    4.                 $string[$key] = $data['new'][$item][$temp[2][$key]] ?? '';
    5.             }
    6.             $text = str_replace($temp[0], $string, $text);
    7.         }
    8. return $text;
    Нужно чтобы обрабатывался массив с множественным вложенностью [arr][arr][arr][arr][arr][arr][arr][arr][arr]!
     
  2. SerfUA

    SerfUA Активный пользователь

    С нами с:
    18 фев 2014
    Сообщения:
    75
    Симпатии:
    4
    Возможно тебе нужно попробовать рекурсивные функции.
     
  3. New_neo

    New_neo Новичок

    С нами с:
    15 ноя 2015
    Сообщения:
    77
    Симпатии:
    3
    А конкретней?
     
  4. denis01

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

    С нами с:
    9 дек 2014
    Сообщения:
    12.230
    Симпатии:
    1.715
    Адрес:
    Молдова, г.Кишинёв
    Попробуй рекурсией
     
  5. New_neo

    New_neo Новичок

    С нами с:
    15 ноя 2015
    Сообщения:
    77
    Симпатии:
    3
    Рекурсией да! Нужен пример!
     
  6. SerfUA

    SerfUA Активный пользователь

    С нами с:
    18 фев 2014
    Сообщения:
    75
    Симпатии:
    4
    ммм. Извини на коде не опишу, потому что я его не совсем правильно понял. Но суть примерно такая.
    У тебя есть функция в которую передаешь массив, к примеру mnog_array($array, $all_result)
    В нее ты передает свой многомерный массив. И такая вещь, в ней есть цикл который проходит массив и сразу же обрабатывает твои элементы, если же в элементе есть еще массивы ты запихаешь этот элемент с массивом в свою функцию, которая опять все это обрабатывает и гоняет. И походу действия запихиваешь это все в $all_result и на выходе получишь массив с ответами по многомерному массиву. Я вообще плохо объясняю
    по этому дам маленький пример рекурсивной функции с многомерными массивами. Но хочу уточнить. Что если ты с рекурсией не знаком то сразу ты это точно не поймешь. Это нужно будет все хорошенечко подучить и тогда копать дальше как это реализовать.
    PHP:
    1. <?php
    2. $arr =Array(
    3.         254362=>Array(254370,  254363),254363=>Array(254369  ),
    4.         254357=>Array(254362,254359),254359=>Array(254360),
    5.         254369=>Array(253000),Array(254357)
    6.     );
    7.  
    8. var_dump(get_childs($arr,254362));
    9.  
    10. function get_childs(&$array, $id){
    11.    static $childs=[];
    12.    static $allkey=[];
    13.    if(!array_key_exists($id,$array))returnfalse;
    14.    foreach($array[$id]as $value){
    15.         $childs[$id]= $array[$id];
    16.         if(!in_array($value,$allkey)){
    17.            $allkey[]=$value;
    18.            get_childs($array, $value);
    19.         }
    20.     }
    21.   return $childs;
    22. }
    23. ?>
     
  7. alexblack

    alexblack Старожил

    С нами с:
    20 янв 2016
    Сообщения:
    640
    Симпатии:
    381
    PHP:
    1. $arr = [1,2=>[3,4=>[5,6,7=>[8,9]]]];
    2. function test_print($item, $key)
    3. {
    4.     echo $item + 2 ."\n";
    5. }
    6.  
    7. array_walk_recursive($arr, 'test_print');
    Код (Text):
    1. 3
    2. 5
    3. 7
    4. 8
    5. 10
    6. 11
     
    HeavyLady, denis01 и [vs] нравится это.
  8. abrdabr

    abrdabr Новичок

    С нами с:
    28 янв 2017
    Сообщения:
    774
    Симпатии:
    65
    @New_neo не проще применить array_map?
     
  9. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
  10. abrdabr

    abrdabr Новичок

    С нами с:
    28 янв 2017
    Сообщения:
    774
    Симпатии:
    65
    @[vs] ну а зачем рекурсия если можно сразу применить пользовательскую функцию к каждому элементу массива, или я не правильно понял что нужно автору?
     
  11. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    @abrdabr функция array_map не обойдет вложенные элементы. Придется делать рекурсивную пользовательскую функцию. Идеально подходит array_walk_recursive из поста @alexblack
     
  12. prohodiltut

    prohodiltut Активный пользователь

    С нами с:
    4 фев 2017
    Сообщения:
    21
    Симпатии:
    2
    Если я правильно понял смысл вопроса, то надо вывести найденые шаблоны в каждый массив.
    Идея такая
    PHP:
    1. <?php
    2. if(preg_match_all("/\[d-(.*?)\|(.*?)\]/", $text, $temp))
    3.    {
    4.    foreach($temp  as $str)
    5.          {
    6. // разбиваем строку массива с помощью разделителя и заносим её в другой массив
    7.                $line = explode(" ", $str);
    8.           };
    9.    };
    10. //вывод массива          
    11. for ($i = 0; $i < count($line); $i++)
    12.          {
    13.          echo $line[$i], "<br />";
    14.           };
    15. ?>
    Может поможет с реализацией?
     
  13. abrdabr

    abrdabr Новичок

    С нами с:
    28 янв 2017
    Сообщения:
    774
    Симпатии:
    65
    @[vs] не заметил я его поста((
     
  14. New_neo

    New_neo Новичок

    С нами с:
    15 ноя 2015
    Сообщения:
    77
    Симпатии:
    3
    Код (Text):
    1. if(preg_match_all("/\[d-(.*?)\|(.*?)\]/", $text, $temp)) {
    2.             $string = '';
    3.             foreach($temp[1] as $key => $item) {
    4.                 $string[$key] = $data['new'][$item][$temp[2][$key]] ?? '';
    5.             }
    6.             $text = str_replace($temp[0], $string, $text);
    7.         }
    8. return $text;
    Обрабатывает массив [array][array][array]
    А нужно неизвестное количество [array]
     
  15. SerfUA

    SerfUA Активный пользователь

    С нами с:
    18 фев 2014
    Сообщения:
    75
    Симпатии:
    4
    Так для этого мы тебе и з самого начала сказали использовать рекурсию. Пожалуйста почитай что это такое. А когда усвоишь материал то поймешь что это то что тебе нужно.
     
  16. kot_k_k

    kot_k_k Активный пользователь

    С нами с:
    22 июл 2014
    Сообщения:
    46
    Симпатии:
    1
    вот самая примитивная рекурсия

    PHP:
    1.   class Recurse
    2.   {
    3.    
    4.       public $res = 0;
    5.       public function Rec($array)
    6.         {
    7.             if (is_array($array))
    8.             {
    9.                 foreach ($array as $ar)
    10.                              $this->Rec($ar) ;     //  это и есть рекурсивный запуск.
    11.             }else
    12.             {
    13.                 $this->res += $array;   //    вот тут делаем то что нужно с каждым элементом массива. в данном случае просто вычисяется сумма всех элементов
    14.             }
    15.             return $this->res;
    16.         }  
    17.   }
    18.   $arr = array(array(1,4,6),array(1,5,6),array(8,4,6),array(1,4,16),array(21,121,43,45,4,6),array(1,4,6));
    19.   $cl = new Recurse();
    20.   $tmp = $cl->Rec($arr);
     
  17. New_neo

    New_neo Новичок

    С нами с:
    15 ноя 2015
    Сообщения:
    77
    Симпатии:
    3
    Я думаю нужно что-то типа
    Код (Text):
    1. public static function trace($text ,  $data = null) {
    2.         if(preg_match_all("/\[d-(.*?)\|(.*?)\]/", $text, $temp)) {
    3.             $string = '';
    4.             foreach($temp[1] as $key => $item) {
    5.                 if (is_array($item)) {
    6.                     trace($item, $text);
    7.                 } else {
    8.                     $string[$key]  = $data['config'][$item][$temp[2][$key]] ?? '';
    9.                 }
    10.             }
    11.             $text = str_replace($temp[0], $string, $text);
    12.         }
    13.         return $text;
    14.     }
    Только вот беда не работает!
     
  18. kot_k_k

    kot_k_k Активный пользователь

    С нами с:
    22 июл 2014
    Сообщения:
    46
    Симпатии:
    1
    тебе надо проверку на is_array надо дополнительно вставить вставить до if
    вернее перенести - когда срабатывает if - это значит элемент массива
     
    #18 kot_k_k, 7 мар 2017
    Последнее редактирование: 7 мар 2017
  19. New_neo

    New_neo Новичок

    С нами с:
    15 ноя 2015
    Сообщения:
    77
    Симпатии:
    3
    А конкретнее на примере можете?
     
  20. kot_k_k

    kot_k_k Активный пользователь

    С нами с:
    22 июл 2014
    Сообщения:
    46
    Симпатии:
    1
    тип того
    PHP:
    1. public static function trace($text ,  $data = null) {
    2. if (is_array($text))
    3. foreach ($text  as $t)
    4.                     trace($t, $text);
    5.                  else
    6.         if(preg_match_all("/\[d-(.*?)\|(.*?)\]/", $text, $temp)) {
    7.             $string = '';
    8.             foreach($temp[1] as $key => $item) {
    9.                
    10.                     $string[$key]  = $data['config'][$item][$temp[2][$key]] ?? '';
    11.                
    12.             }
    13.             $text = str_replace($temp[0], $string, $text);
    14.         }
    15.         return $text;
    16.     }

    но что мешает воспользоваться тем что я предложил?
    в 13-ю строку вставляешь свою обработку if(preg_match_all .....
    только правильно надо нарисовать $this->res
     
  21. New_neo

    New_neo Новичок

    С нами с:
    15 ноя 2015
    Сообщения:
    77
    Симпатии:
    3
    Все равно не работает !
     
  22. kot_k_k

    kot_k_k Активный пользователь

    С нами с:
    22 июл 2014
    Сообщения:
    46
    Симпатии:
    1
    дай массив
     
  23. New_neo

    New_neo Новичок

    С нами с:
    15 ноя 2015
    Сообщения:
    77
    Симпатии:
    3
    Правильное решение!
    Код (Text):
    1. if(preg_match_all("/\[d-(.*?)\]/", $text, $temp)) {
    2.             if(!isset($data['config'])) $data['config'] = Config::instance()->config;
    3.                 $string = '';
    4.                 foreach($temp[1] as $key => $item) {
    5.                 $arr = explode("|", $item);
    6.                 $tmp = null;
    7.                 foreach($arr as $v) {
    8.                   if(isset($tmp)) {
    9.                     if(!isset($tmp[$v])) continue;
    10.                     $tmp = $tmp[$v];
    11.                   } else {
    12.                     if(!isset($data['config'][$v])) continue;
    13.                     $tmp = $data['config'][$v];
    14.                   }
    15.                 }
    16.                 $string[$key] = $tmp ?? '';
    17.             }
    18.             $text = str_replace($temp[0], $string, $text);
    19.         }
    20.         return $text;