简体   繁体   中英

What would be the best way to simplify this foreach?

I was testing an xml object to see how many levels deep it went and found that it goes 11 elements deep. I'm wondering how I could have done this simpler so that in the future I can save a few minutes.

$xml = simplexml_load_file(drupal_get_path('module', 'my_module') . '/test_file.xml');
  dpm($xml);
  foreach($xml->section as $section_l1) {
    dpm('L1-------------------------------');
    foreach($section_l1->attributes() as $a => $b) {
      dpm($a . ' = ' . $b);
    }
    dpm('-----:');
    foreach($section_l1->section as $section_l2) {
      dpm('---L2--------------------------');
      foreach($section_l2->attributes() as $a => $b) {
        dpm($a . ' = ' . $b);
      }
      dpm('-----:');
      foreach($section_l2->section as $section_l3) {
        dpm('------L3---------------------');
        foreach($section_l3->attributes() as $a => $b) {
          dpm($a . ' = ' . $b);
        }
        dpm('-----:');
        foreach($section_l3->section as $section_l4) {
          dpm('------L4---------------------');
          foreach($section_l4->attributes() as $a => $b) {
            dpm($a . ' = ' . $b);
          }
          dpm('-----:');
          foreach($section_l4->section as $section_l5) {
            dpm('------L5---------------------');
            foreach($section_l5->attributes() as $a => $b) {
              dpm($a . ' = ' . $b);
            }
            dpm('-----:');
            foreach($section_l5->section as $section_l6) {
              dpm('------L6---------------------');
              foreach($section_l6->attributes() as $a => $b) {
                dpm($a . ' = ' . $b);
              }
              dpm('-----:');
              foreach($section_l6->section as $section_l7) {
                dpm('------L7---------------------');
                foreach($section_l7->attributes() as $a => $b) {
                  dpm($a . ' = ' . $b);
                }
                dpm('-----:');
                foreach($section_l7->section as $section_l8) {
                  dpm('------L8---------------------');
                  foreach($section_l8->attributes() as $a => $b) {
                    dpm($a . ' = ' . $b);
                  }
                  dpm('-----:');
                  foreach($section_l8->section as $section_l9) {
                    dpm('------L9---------------------');
                    foreach($section_l9->attributes() as $a => $b) {
                      dpm($a . ' = ' . $b);
                    }
                    dpm('-----:');
                    foreach($section_l9->section as $section_l10) {
                      dpm('------L10---------------------');
                      foreach($section_l10->attributes() as $a => $b) {
                        dpm($a . ' = ' . $b);
                      }
                      dpm('-----:');
                      foreach($section_l10->section as $section_l11) {
                        dpm('------L11---------------------');
                        foreach($section_l11->attributes() as $a => $b) {
                          dpm($a . ' = ' . $b);
                        }
                        dpm('-----:');
                        foreach($section_l11->section as $section_l12) {
                          dpm('------L12---------------------');
                          foreach($section_l12->attributes() as $a => $b) {
                            dpm($a . ' = ' . $b);
                          }
                          dpm('-----:');
                          foreach($section_l12->section as $section_l13) {
                            dpm('------L13---------------------');
                            foreach($section_l13->attributes() as $a => $b) {
                              dpm($a . ' = ' . $b);
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }

Note: drupal_get_path and dpm are Drupal CMS functions and can be ignored here.

Since you're doing a similar thing at each level you can put this logic into a function and call that logic at each level. An (untested) example would be something like:

$xml = simplexml_load_file(drupal_get_path('module', 'my_module') . '/test_file.xml');
function processXML($xml, $level = 1){
    dpm($xml);
    foreach($xml->section as $section_l1) {
         dpm('L'.$level.'-------------------------------');
         foreach($section_l1->attributes() as $a => $b) {
            dpm($a . ' = ' . $b);
         }
         dpm('-----:');
         processXML($section_l1,$level+1);
    }
}

You could use a recursive function :

$xml = simplexml_load_file(drupal_get_path('module', 'my_module') . '/test_file.xml');
dpm($xml);
traverse($xml, 1);

private function traverse($section, $level) {
  dpm('L'.$level.'-------------------------------');

  foreach($section->attributes() as $a => $b) {
    dpm($a . ' = ' . $b);
  }

  dpm('-----:');

  traverse($section->section, $level+1)
}

This should work. Here is an example

function recurse($xml, $maxLevel = -1, $level = 0) {
    if ($maxLevel != -1 && $level > $maxLevel) {
        return;
    }

    if ($level == 0) {
        dpm($xml);
    }

    $string = '---------------------------------';
    $pos = $level * 3;
    $l = 'L'. ($level+1);
    $string = substr_replace($string, $l, $pos, strlen($l));
    foreach ($xml->section as $section) {
        dpm($string);
        foreach ($section->attributes() as $a=>$b) {
            dpm($a .' = '. $b);
        }
        dpm('-----:');
        recurse($section, $maxLevel, $level+1);
    }
}

$xml = simplexml_load_file(drupal_get_path('module', 'my_module') . '/test_file.xml');
recurse($xml);

You can specify the max level you want to go down using the second parameter, as I've done in the codepad example.

You need a recursive function:

$xml = simplexml_load_file(drupal_get_path('module', 'my_module') . '/test_file.xml');
dpm($xml);

$depth = $xml->section; // The array you want to find the depth
$iterator = 0; // The starting level
recurse_count($depth, $iterator); // Fire the function

function recurse_count($array, $iterator) {
    foreach($array->section as $children) {
        $iterator++; // Increment the iterator
        dpm('---L'.$iterator.'--------------------------');
        foreach($children->attributes() as $a => $b) {
            dpm($a . ' = ' . $b);
        }
        dpm('-----:');
    }
    recurse_count($children, $iterator); // Fire the function again
}

A recursive function is one that will call itself and is well suited for your issue. This example should work for your problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM