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


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

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

我要找的是'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()将返回一个数组而不是一个对象,因为如果$assoc设置为true,返回的对象将被转换为关联数组。

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

阅读本文档

在循环的这一层:

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

$device已经指向了唯一id,所以不用:

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

你只需要写:

if($device== "Kn04")

我不明白你为什么要显示uniqueId的值也就是Kn04,因为你知道它,所以也许不用那样:

echo $device;

添加所有函数并返回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";
}
编辑:下一个示例允许您选择值大于阈值参数的sourceid
$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";
}