解析PHP保护密钥中的JSON响应


Parse JSON response in PHP - Protected keys?

我使用Curl在Sage服务器上执行GET请求。响应是JSON格式的,但我无法访问键/值。

响应示例如下:

{
"$descriptor": "Sage Accounts 50 | tradingAccount.",
  "$totalResults": 1508,
  "$startIndex": 1,
  "$itemsPerPage": 1508,
  "$resources": [
   {
      "$url": "http://it1:5493/sdata/accounts50/GCRM/{53C58AA8-1677-46CE-BCBE-4F07FED3668F}/tradingAccountCustomer(9a7a0179-85cb-4b65-9d02-73387073ac83)?format=atomentry",
      "$uuid": "9a7a0179-85cb-4b65-9d02-73387073ac83",
      "$httpStatus": "OK",
      "$descriptor": "",
      "active": true,
      "customerSupplierFlag": "Customer",
      "companyPersonFlag": "Company",
      "invoiceTradingAccount": null,
      "openedDate": "'/Date(1246834800000+0100)'/",
      "reference": "1STCL001",
      "reference2": null,
      "status": "Open"
    }
    /* Additional results omitted for simplicity */
}

我需要为$resources的每个子级访问2个密钥/值对。第一个是$uuid,第二个是reference

我尝试过各种方法,包括:

$result=curl_exec($ch);
$resources = $result->{'$resources'};
print_r($resources); /* Non-object error */

有人能告诉我如何访问这些密钥/值吗?

更新

如果我执行以下操作,我会收到一个Notice: Trying to get property of non-object错误。

$result = json_decode(curl_exec($ch));
$resources = $result->{'$resources'};
print_r($resources);

编辑2

当前使用的整个代码:

<?php 
header('content-type:application/json');
error_reporting(E_ALL);
$url = "http://it1:5493/sdata/accounts50/GCRM/-/tradingAccounts?format=json";
$header = array();
$header[] = 'Authorization: Basic bWFuYWdlcjpjYmwyMDA4';
$header[] = 'Content-Type: application/json;';
//  Initiate curl
$ch = curl_init();
// Will return the response, if false it print the response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the url
curl_setopt($ch, CURLOPT_URL,$url);
// Set the header
curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
// Execute
$result = json_decode(curl_exec($ch));
if ($result === false)
{
    // throw new Exception('Curl error: ' . curl_error($crl));
    print_r('Curl error: ' . curl_error($ch));
}
// Closing
curl_close($ch);
// Access property $resources
$resources = $result->{'$resources'};
// Dump results
print_r($resources);

?>

编辑3

var_dump($result); 输出

string '{
   "$descriptor": "Sage Accounts 50 | tradingAccount",
   "$totalResults": 1508,
   "$startIndex": 1,
   "$itemsPerPage": 1508,
   "$resources": [
      {
       "$url": "http://it1:5493/sdata/accounts50/GCRM/{53C58AA8-1677-46CE-BCBE-4F07FED3668F}/tradingAccountCustomer(9a7a0179-85cb-4b65-9d02-73387073ac83)?format=atomentry",
       "$uuid": "9a7a0179-85cb-4b65-9d02-73387073ac83",
       "$httpStatus": "OK",
       "$descriptor": "",
       '... (length=5333303)

服务器返回编码为UTF-8的JSON,其中BOM将3个字符放在字符串的开头。只需尝试获得正确编码的JSON,如果不能,请删除前3个字符,然后使用json_decode获取PHP对象。

更新:
服务器响应是用BOM(字节顺序标记(编码的UTF-8,这导致json_encodeJSON_ERROR_SYNTAX 中失败

工作代码

$string = curl_exec($ch);
$object = json_decode(remove_utf8_bom($string),true);

foreach ($object as $key => $value)
    if (is_array($value))
        foreach($value as $k=>$arr){
            print $arr['$uuid'] . PHP_EOL;
            print $arr['reference'] . PHP_EOL;
        }
function remove_utf8_bom($text)
{
    $bom = pack('H*','EFBBBF');
    $text = preg_replace("/^$bom/", '', $text);
    return $text;
}

remove_utf8_bom函数从此处剥离https://stackoverflow.com/a/15423899/5043552


假设$result是您最近编辑的json_decode的内容,这就是您访问键/值的方式。

foreach ($result->{'$resources'} as $obj){
    print $obj->{'$uuid'} . PHP_EOL;
    print $obj->reference . PHP_EOL;
}
// prints out
// 9a7a0179-85cb-4b65-9d02-73387073ac83
// 1STCL001

您缺少json_decode调用。试试这个:

$result = json_decode(curl_exec($ch));
$resources = $result->{'$resources'};
$result = json_decode(curl_exec($ch)); // Decode the JSON
$resources = $result->{'$resources'}; // Access the $resources property which is an array
print_r($resources); // Prints an array
$result = json_decode(curl_exec($ch));
$resources = $result->{'$resources'};

您必须解码JSON

其他人似乎都缺少的关键事实是,$resources是JSON中定义的as数组,而不是对象,因此json_decode()将把它变成PHP数组,而非PHP对象。

$result = json_decode(curl_exec($ch));
$resources = $result['$resources'];   //resources is an array, not an object.
foreach ($resources as $resource) {
    //but each resource is an object...
    print $resource->{'$url}."'n";
    print $resource->{'$uuid}."'n";
    // ...etc...
}