найти путь к ключу в JSON в PHP

#php #json

#php #json

Вопрос:

У меня есть данные, представленные в формате JSON. Это может выглядеть следующим образом:

 $obj = {
  "lang": "en",
  "langLong": "english",
  "menu": ["Services", "About us", "Contact"],
  "pages": {
    "homepage": {
      "code": "homepage",
      "welcomeHeading": "Lorem ipsum dolor sit amet",
      "welcomeSubHeading": "Lorem ipsum dolor sit amet",
      "welcomeLink": "Lorem ipsum dolor sit amet",
      "aboutHeading": "Lorem ipsum dolor sit amet",
      "aboutSubHeading": "Ing. John Doe, FCCA",
      "aboutDescription": "Founder John Doe Lorem ipsum dolor sit amet",
      "ourServicesHeading": "Our services",
      "redBlocks": [
        {
          "heading": "Interim management",
          "items": ["first item", "second item"]
        },
        {
          "heading": "second service",
          "items": ["first item", "second item"]
        }
      ]
    },
    "services": {
      "code": "services",
      "welcomeHeading": "Interim management",
      "blocks": [
        {
          "heading": "Substitute interim management",
          "items": [
            {
              "subHeading": "target",
              "description": "
          "items": ["first item", "second item"]"
            }
          ]
        }
      ]
    }
    }
}
  

Я выполняю поиск функции, которая использует ключ (например, ourServicesHeading) и объект и возвращает путь к искомому ключу.

Я пытался написать функцию для этого, которая приведена ниже. И одной из проблем, с которыми я сталкиваюсь, является преобразование между объектом и ассоциативным массивом.

 public function findPath($obj, $key) {
            $list = array();
            if(!$obj) {
                return $list;
            }
            if(is_array($obj)) {
                foreach ($obj as $item => $value) {
                    $list = array_merge($list,[$item]);
                }
                return $list;
            }
            if(in_array($key, (array) $obj)) {
                $list = array_push($list, $obj[$key]);
            }
            if(is_object($obj) amp;amp; $obj != null) {
                $children = array_keys(json_decode(json_encode($obj), true));
                $obj = json_decode(json_encode($obj), true);
                if(sizeof($children) > 0) {
                    foreach($children as $item => $value) {
                        $result = $this->findValuesHelper($obj[$children[$item]], $key);

                        $list = array_merge($list, $result);
                    }
                }
            }
            return $list;
    }

  

и в результате из функции

 $res = findPath($obj, "ourServicesHeading")
// "pages/homepage/ourServicesHeading"
  

Ответ №1:

Не уверен, зачем вам продолжать преобразовывать различные части из JSON и объектов, вы можете преобразовать JSON в представление на основе массива, используя второй параметр одного вызова json_decode() .

Этот код просто преобразует JSON в массив, затем вызывает findPath() метод. Я только что использовал print_r() для вывода результатов здесь для тестирования.

Я добавил комментарии к коду, чтобы объяснить основной код…

 $json = json_decode($obj, true);

print_r(findPath($json, "ourServicesHeading"));

function findPath ( $obj, $key, $path = '' )    {
    $list = [];

    foreach ( $obj as $itemKey => $item )   {
        // Check if it's a field I'm interested in (force to string in case of a number)
        if ( (string)$itemKey == $key ) {
            // Add the matched item
            $list[] = $path."/".$itemKey;
        }
        if ( is_array($item) )  {
            // Recall this function again for next level of data, merge in the results
            $list = array_merge($list, findPath($item, $key, $path."/".$itemKey));
        }
    }

    // Pass up results
    return $list;
}
  

результат таков

 Array
(
    [0] => /pages/homepage/ourServicesHeading
)
  

Вам нужно будет добавить части public и $this-> , поскольку я написал это как независимую функцию.