2016-03-01 4 views
-1

Я делаю некоторые тесты с использованием Behat, PHP и Guzzle для создания HTTP-запросов. Один из моей просьбы принес мне это тело ответа JSon:PHP - получить значение ключа в Json

{ 
     "products":[ 
      { 
      "id":1466367, 
      "sku":"PO870SHB32LET", 
      "name":"T\u00eanis Polo Ralph Lauren Kids Day Bege", 
      "brand_id":20901, 
      "brand":"Polo Ralph Lauren Kids", 
      "description":"test test test abc", 
      "price":124.9, 
      "original_price":179, 
      "gender":[ 
       "menino", 
       "masculino" 
      ] 
      } 
     ] 
    } 

Итак, я сделал эту функцию, чтобы получить значение:

public function getJsonFieldValue($keyword) 
    { 
     $responseBody = $this->getResponse()->json(); 
     $jsonFieldValue = $this->recursiveFieldKeySearch($keyword,$responseBody);   
    } 

    public function recursiveFieldKeySearch($needle,$haystack) { 
      foreach($haystack as $key=>$value) 
      { 
       $current_key = $key; 
       if(!is_array($value) && $needle===$key) { 
        return $value; 
       } 

       if (is_array($value)) { 
        return self::recursiveFieldKeySearch($needle,$value); 
       } 
      } 
      return false; 
     } 

Если значение равно «идентификатор», например, функция может найти и вернуть значение. Проблема в том, что когда я хочу получить значения «gender», моя функция всегда возвращает FALSE для меня. Кто-нибудь может мне помочь, пожалуйста?

Спасибо!

+1

Почему вы "recursiveFieldKeySearch()"? Не зафиксирована ли структура ответа? Разве вы не знаете структуру? Такая общая функция, по-видимому, помогает, но на самом деле она может затруднить обнаружение ошибок. Напишите функцию для каждого важного значения из '$ responseBody', и все станет более понятным. – axiac

+1

Нет элемента с ключом 'gender', который не имеет массива в качестве его значения, поэтому вы его никогда не найдете. И это не способ поиска вашей структуры, так как вы найдете произвольное значение, когда ключи не уникальны. Например, '0' в этом случае. – jeroen

+0

@DiegoUlrichZegaib просто проверьте на is_array, если найдена игла. Посмотрите на мой ответ. – Kordi

ответ

0

Думайте, вы должны изменить эти строки кода. В принципе, если игла является массивом, верните его.

if (is_array($value)) { 
    return self::recursiveFieldKeySearch($needle,$value); 
} 

в

if (is_array($value) && $needle === $key) { 
    return $value; 
} else if (is_array($value)) { 
    return self::recursiveFieldKeySearch($needle,$value); 
} 

Приложение по @trincot

Есть некоторые значения, где ваш алгоритм не является правильным.

Пример

{ 
    "products":[ 
     { "a":1 }, 
     { 
      "id":1466367, 
      ...etc. 
     } 
    ] 
} 

Вот ваш алгоритм не найдет идентификатор.

Лучше Алгоритм

public function recursiveFieldKeySearch($needle, $haystack) { 
    if (!is_array($haystack))  return false; 
    if (isset($haystack[$needle])) return $haystack[$needle]; 

    foreach ($haystack as $key=>$value) { 
     $result = self::recursiveFieldKeySearch($needle, $value); 
     if ($result !== false) return $result; 
    } 
    return false; 
} 

Благодаря @trincot для Приложения

+0

Спасибо, Корди !! –

+0

добро пожаловать, было бы неплохо, если бы вы продвинули мой ответ, а затем в качестве полезного ответа и повысили его ;-) ... – Kordi

+0

Это не всегда находит нужное значение. – trincot

0

Есть больше проблем с кодом. Например, если у вас будет два брата, и ключ находится где-то во втором, ваш код его не найдет.

Пример:

Если в вашем JSON строку, которую вы бы добавить { "a":1 }, в качестве первого элемента «продуктов», как это:

{ 
    "products":[ 
     { "a":1 }, 
     { 
      "id":1466367, 
      ...etc. 
     } 
    ] 
} 

затем с кодом вы не найдете "id". Это связано с тем, что функция выйдет с false еще до получения второго элемента массива «Продукты».

Решение

Попробуйте вместо этого:

public function recursiveFieldKeySearch($needle, $haystack) { 
    if (!is_array($haystack))  return false; 
    if (isset($haystack[$needle])) return $haystack[$needle]; 

    foreach ($haystack as $key=>$value) { 
     $result = self::recursiveFieldKeySearch($needle, $value); 
     if ($result !== false) return $result; 
    } 
    return false; 
} 
+0

Привет, большое вам спасибо. Но вы правы, если у меня есть два одинаковых ключа, но с разными значениями функция вернет первый. Другими словами, мое утверждение может терпеть неудачу, но не является ошибкой, потому что мой код просто игнорирует остальные ключи с тем же именем. –

+0

Добро пожаловать. Я, вероятно, не совсем понял, что я обнаружил, что ваш код отсутствует, кроме того, что вы упомянули в вопросе. Поэтому для полноты я добавил пример в свой ответ, показывая случай, когда ваш исходный код не найдет ключ, если он присутствует в массиве, что сам является вторым элементом массива родителя. Вы можете использовать это в качестве тестового примера для других ответов. – trincot

Смежные вопросы