尝试在 JSON 字段中搜索并不总是存在的特定值

Trying to search JSON for a particular value in a field that is not always there

我有下面的 JSON 数组,我在 uniqueID 对象中寻找一个特定值。问题是这个字段并不总是存在,因为它是一个字段之外的对象。

我要的是'Kn04'

{
  "searchMeta": {
    "maxResults": 100,
    "sourceId": "6e5c1d5d-d84b-4b64-9d2c-a32b8c9f7174",
    "iso8601Timestamps": true,
    "sourceType": "VENUE",
    "endTimestamp": 1444952156,
    "startTimestamp": 1444952056
  },
  "ranges": [
    {
      "clients": [
        {
          "clientId": {
            "mac": "6c:19:8f:bf:47:e9"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -93.3
            }
          ]
        },
        {
          "clientId": {
            "uniqueId": "Kn04"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -75.3
            }
          ]
        },
        {
          "clientId": {
            "mac": "58:6d:8f:75:95:0e"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -86.2
            }
          ]
        },
        {
          "clientId": {
            "mac": "44:d9:e7:21:e0:de"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -25.8
            }
          ]
        },
        {
          "clientId": {
            "mac": "68:72:51:10:e7:26"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -47
            }
          ]
        },
        {
          "clientId": {
            "mac": "68:72:51:10:e7:29"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -72.3
            }
          ]
        },
        {
          "clientId": {
            "mac": "a4:ee:57:2e:ac:bd"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -95
            }
          ]
        },
        {
          "clientId": {
            "uniqueId": "CQos"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -64.1
            }
          ]
        },
        {
          "clientId": {
            "mac": "86:8f:c2:8f:c3:20"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -68.4
            }
          ]
        },
        {
          "clientId": {
            "mac": "32:91:8f:6c:2e:f4"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -87.7
            }
          ]
        },
        {
          "clientId": {
            "mac": "30:91:8f:6c:2e:f3"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -86.9
            }
          ]
        },
        {
          "clientId": {
            "mac": "30:91:8f:43:ca:49"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -87
            }
          ]
        },
        {
          "clientId": {
            "mac": "1d:8b:90:7b:20:9c"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -102.5
            }
          ]
        },
        {
          "clientId": {
            "mac": "38:2c:4a:5c:b6:a0"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -76.7
            }
          ]
        },
        {
          "clientId": {
            "uniqueId": "ECgg"
          },
          "rssis": [
            {
              "sourceId": "zR1L3",
              "value": -59.5
            }
          ]
        }
      ],
      "timestamp": "2015-10-15T23:35:00+00:00"
    }
  ]
}

我目前的代码如下,但它不起作用。 $response 是 JSON 数组名称

$json = json_decode($response,true);


foreach($json['ranges'] as $range){
foreach($range['clients'] as $client)
foreach($client['clientId'] as $client1 => $device)
{
    if($device['uniqueId'] == "Kn04")
    {
        echo $device=>uniqueId;
    }
}}

首先,json_decode() 将 return 一个数组而不是一个对象,因为如果 $assoc 设置为 true,returned 对象将是转换为关联数组。

mixed json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] )

读这个documentation

在循环的这个级别:

foreach($client['clientId'] as $client1 => $device)

$device 已经引用了 uniqueId,所以不是:

 if($device['uniqueId'] == "Kn04")

你只需要写:

if($device== "Kn04")

而且我不明白你为什么要显示 uniqueId 的值,即 Kn04,因为你知道它,所以也许可以代替它:

echo $device;

在一个函数中添加所有内容并return一个truefalse响应

$json = json_decode($response, true);

function findDevice($id) {
    global $json;
    foreach($json['ranges'] as $range) {
        foreach($range['clients'] as $client) {
            foreach($client['clientId'] as $client1 => $device) {    
                if($device==$id) return true; // or return sthing else
            }
        }
    }
    return false;   
}

这是您可以使用的递归函数。递归搜索的妙处在于它不关心数组结构。如果以后出现更多级别 - 您无需更改任何内容。另外 - 我不明白你为什么要打印已知的 id 所以在我的例子中它打印了整个设备

$json = json_decode($response,true);

function findRecursive($array, $needle){

    if(is_array($array)){
        foreach($array as $key => $item){

            if($item === $needle){
                return $array;
            }

            $found = findRecursive($item, $needle);

            if($found != false){
                return $found;
            }
        }
    } else return false;
}

$device = findRecursive($json, 'Kn04');

if($device) {
    print_r($device);
} else {
    echo "Not found";
}

编辑:下一个示例允许您select sourceIds 的值大于阈值参数

$json = json_decode($response,true);

function matchSidsByThresholdRecursive($array, $treshold, &$results){

if(is_array($array)){

    //If this is the array we are looking for - it has to have both 'sourceId' and 'value' indexes
    if(isset($array['sourceId']) && isset($array['value'])){
        //The current value is greater than threshold? Add the corresponding sourceId to results
        if($array['value'] > $treshold){
            $results[] = $array['sourceId'];
        }
    }

    //If one of the subitems is an array - iterate through it the same way
    foreach($array as $item){
        if(is_array($item)){
            matchSidsByThresholdRecursive($item, $treshold, &$results);    
        }                        
      }
    }     
}

$results = array();

//This will populate the $results array with sourceIds with the values greater than -50
matchSidsByThresholdRecursive($json, -50, $results);

if($results) {
    print_r($results);
} else {
    echo "Not found";
}