2014-09-13 54 views
0

我正在尋找一個乾淨的解決方案來轉換嵌套數組。遍歷嵌套數組並轉換一些值

這裏就是我想實現...

原始數組:

$map = array(
    'name' => 'super test', 
    'machine_name' => 'super_test', 
    'class' => 'openlayers_map_map', 
    'options' => array(
     'width' => 'auto', 
     'height' => '300px', 
     'contextualLinks' => 1, 
     'provideBlock' => 1, 
     'view' => array(
     'center' => array(
      'lat' => '0', 
      'lon' => '0', 
     ), 
     'rotation' => '0', 
     'zoom' => '2', 
    ), 
     'layers' => array(
     '0' => array(
      'name' => 'Ma super layer', 
      'machine_name' => 'plouf', 
      'class' => 'openlayers_layer_tile', 
      'options' => array(
      'source' => array(
       'name' => 'Ma super layer', 
       'machine_name' => 'plouf', 
       'class' => 'openlayers_source_osm' 
      ), 
      'param1' => 'ca roule' 
     ) 
     ), 
    ), 
     'controls' => array(
     'control_mouseposition', 
     '0' => array(
      'name' => 'Control attribution', 
      'machine_name' => 'openlayers_control_attribution', 
      'class' => 'openlayers_control_attribution', 
      'options' => array(
      'collapsible' => 1 
     ) 
     ), 
     'control_rotate', 
     'control_zoom', 
    ), 
     'interactions' => array(
     'interaction_doubleclickzoom', 
     'interaction_dragpan', 
     'interaction_dragrotateandzoom', 
     'interaction_mousewheelzoom', 
    ), 
    ) 
); 

最終陣列:

$map = array(
    'name' => 'super test', 
    'machine_name' => 'super_test', 
    'class' => 'openlayers_map_map', 
    'options' => array(
     'width' => 'auto', 
     'height' => '300px', 
     'contextualLinks' => 1, 
     'provideBlock' => 1, 
     'view' => array(
     'center' => array(
      'lat' => '0', 
      'lon' => '0', 
     ), 
     'rotation' => '0', 
     'zoom' => '2', 
    ), 
     'layers' => array(
     '0' => (object) openlayers_layer_tile 
      'name' => 'Ma super layer', 
      'machine_name' => 'plouf', 
      'class' => 'openlayers_layer_tile', 
      'options' => array(
      'source' => (object) openlayers_source_osm 
       'name' => 'Ma super layer', 
       'machine_name' => 'plouf', 
       'class' => 'openlayers_source_osm' 
      ), 
      'param1' => 'ca roule' 
     ) 
     ), 
    ), 
     'controls' => array(
     'control_mouseposition', 
     '0' => (object) openlayers_control_attribution 
      'name' => 'Control attribution', 
      'machine_name' => 'openlayers_control_attribution', 
      'class' => 'openlayers_control_attribution', 
      'options' => array(
      'collapsible' => 1 
     ) 
     ), 
     'control_rotate', 
     'control_zoom', 
    ), 
     'interactions' => array(
     'interaction_doubleclickzoom', 
     'interaction_dragpan', 
     'interaction_dragrotateandzoom', 
     'interaction_mousewheelzoom', 
    ), 
    ) 
); 

基本上,我需要遍歷數組,發現所有帶有「班級」鑰匙的孩子,並將其轉換成同名的對象。

回答

1

如果您沒有準備好實例化的類,則此代碼將創建匿名對象。 (類名仍然存在的屬性。)

function class_to_object (&$arr) { 

    if (is_array($arr)) { 
    foreach ($arr as $key => &$val) { 
     class_to_object($val); 
    } 

    if (isset($arr['class'])) { 
     $arr = (object) $arr; 
    } 
    } 

} 

class_to_object($map); 

結果:

(注意,第一個陣列變成一個對象,因爲它包含字段「類」嫌我猜你可以輕鬆調整功能,如果你不想要那樣的行爲)

stdClass Object 
(
    [name] => super test 
    [machine_name] => super_test 
    [class] => openlayers_map_map 
    [options] => Array 
     (
      [width] => auto 
      [height] => 300px 
      [contextualLinks] => 1 
      [provideBlock] => 1 
      [view] => Array 
       (
        [center] => Array 
         (
          [lat] => 0 
          [lon] => 0 
         ) 

        [rotation] => 0 
        [zoom] => 2 
       ) 

      [layers] => Array 
       (
        [0] => stdClass Object 
         (
          [name] => Ma super layer 
          [machine_name] => plouf 
          [class] => openlayers_layer_tile 
          [options] => Array 
           (
            [source] => stdClass Object 
             (
              [name] => Ma super layer 
              [machine_name] => plouf 
              [class] => openlayers_source_osm 
             ) 

            [param1] => ca roule 
           ) 

         ) 

       ) 

      [controls] => Array 
       (
        [0] => stdClass Object 
         (
          [name] => Control attribution 
          [machine_name] => openlayers_control_attribution 
          [class] => openlayers_control_attribution 
          [options] => Array 
           (
            [collapsible] => 1 
           ) 

         ) 

        [1] => control_rotate 
        [2] => control_zoom 
       ) 

      [interactions] => Array 
       (
        [0] => interaction_doubleclickzoom 
        [1] => interaction_dragpan 
        [2] => interaction_dragrotateandzoom 
        [3] => interaction_mousewheelzoom 
       ) 

     ) 

) 
+0

謝謝,這就是我一直在尋找的。 – 2014-09-16 08:40:12

0

這沒有經過測試的遞歸函數,可以讓你在正確的軌道上:

function recursive_hydrate_array($arr) 
{ 
    if(!is_array($arr) || !isset($arr["class"])) 
    { 
    throw new Exception("Argument is not an array or does not have a 'class' key."); 
    } 

    $klass = $arr["class"]; 
    unset($arr["class"]); 

    $obj = new $klass(); 

    foreach($arr as $k => $v) 
    { 
    if(is_array($arr[$k]) && isset($arr[$k]["class"])) 
    { 
     $obj->{$k} = recursive_hydrate_array($arr[$k]); 
    } 
    else 
    { 
     $obj->{$k} = $arr[$k]; 
    } 
    } 

    return $obj; 
} 

請注意,我在這裏做三個假設:

  1. 有問題的類已經存在。
  2. 每個類都可以實例化,而不需要傳遞任何參數給它的構造函數。
  3. 每個類的所有相關屬性都是公共的,並且可以從課外設置。