簡體   English   中英

刪除未知級別的數組動態(不使用eval)

[英]Deleting unknown level of array dynamic(not using eval)

我將有很多未知的數組級別; 我想刪除所選的。

例:

$data = array(
  'level1' => array(
      'level2' => array(
          'level3' => array(
             'level4' => 'the end level at currently example, but not always',
             'level4_remain' => 'this data will remain'
          ),
          'remain' => 'this data would not delete in this example too'
      )
   )
   'root' => 'this data would not delete in this example'
);

我有一個叫vars的課; 它存儲了我可以隨時獲取的全局變量; 隨時添加,但現在我要制作刪除方法,我擔心多層次的問題:

class vars {
   public static $data = array();

   public static function get($key){
      $key = explode('/', $key);
      $v = self::$data;

      foreach($key as $k)
      {

          if(!isset($v[$k]))
          {
              return null;
          }

          $v = &$v[$k];
      }

      return $v;
   }

   public static function has($key){
       .........
   }

   public static function del($key){
       $key = explode('/', $key);
       //....Any idea how to do this....//
   }
}

我將使用這樣的get方法:

$blabla = vars::get('level1/level2/level3/level4');

並返回正確的數據,但在del method ,我不知道該怎么做:

$deleted = vars::del('level1/level2/level3/level4');

刪除數組后需要完成:

unset($data['level1']['level2']['level3']['level4']);

在做了一些研究后我發現了這個,但這只是針對“set”級別的數組,而不是自動設置為盡可能多的級別:

foreach ($data as $k1 => $arr) {
    foreach ($arr as $k2 => $arr2) {
        foreach ($arr2 as $k3 => $arr3) {
            if ($k3 == $key) {
                unset($rules[$k1][$k2][$k3]);
            }
        }
    }
}

而且我認為它可以這樣做,但是非常難看:

foreach($data as $k1 => $arr1){
   if(is_array($arr1)){
      foreach($arr1 as $k2 => $arr2){
          //...keep writing the if(is_array()){}else{} and foreach(){} for more level deeper...//
      }
   }else{
      //...the unset should be here...//
   }
}

經過一些研究, eval可能是有害的,所以任何人都有任何想法如何使用除eval之外的任何方法來做到這一點?

如果你不介意使用eval ......

public static function del($levels)
{
    $lvls = explode('/', $levels);
    $count = count($lvls);
    $eval = '';

    for ($i=0; $i<$count; ++$i) {
        // Current Array Key
        $key = $lvls[$i];
        $eval .= "['$key']"; 
    }
    $eval = 'self::data' . $eval;
    eval("unset($eval);");
}

但是,通過eval運行不受信任(如用戶輸入)可能很危險。

為避免eval ,您可以進行遞歸路由。 訣竅是遍歷你的索引並重復傳遞一個子數組引用,類似於你的get函數,只是遞歸。

public static function del($key){
   $key = array_reverse( explode('/', $key) ); // _reverse for _pop later
   del_r(self::$data,$key); // start the recursive function
}

private static function del_r(&$array,$keys) { // shouldn't be used from outside
    $key = array_pop($keys); // extract next key, this removes it from $keys
    if (count($keys)) { // still keys left -> recurse further
        del_r($array[$key],$keys); // pass subarray by reference
    }
    else { // no more keys -> delete the element at the current $key
        unset($array[$key]);
    }
}

根據鍵的數量,您可以使用array_shift()而不是array_pop()並刪除array_reverse()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM