首页 > 解决方案 > PHP json_decode - 从对象、数组、对象中提取特定值

问题描述

我有这个json:

{"id":"***hidden***","event_version":"1.0","create_time":"2020-07-28T04:09:33.415Z","resource_type":"checkout-order","resource_version":"2.0","event_type":"CHECKOUT.ORDER.APPROVED","summary":"An order has been approved by buyer","resource":{"update_time":"2020-07-28T04:09:05Z","create_time":"2020-07-28T04:08:53Z","purchase_units":[{"reference_id":"default","amount":{"currency_code":"CAD","value":"50.00"},"payee":{"email_address":"***hidden**","merchant_id":"***hidden***"},"custom_id":"THISVALUEIWANT","shipping":{"name":{"full_name":"John Doe"},"address":{"address_line_1":"1 Maire-Victorin","admin_area_2":"Toronto","admin_area_1":"ON","postal_code":"M5A 1E1","country_code":"CA"}},"payments":{"captures":[{"id":"***hidden***","status":"COMPLETED","amount":{"currency_code":"CAD","value":"50.00"},"final_capture":true,"seller_protection":{"status":"ELIGIBLE","dispute_categories":["ITEM_NOT_RECEIVED","UNAUTHORIZED_TRANSACTION"]},"seller_receivable_breakdown":{"gross_amount":{"currency_code":"CAD","value":"50.00"},"paypal_fee":{"currency_code":"CAD","value":"1.75"},"net_amount":{"currency_code":"CAD","value":"48.25"}},"links":[{"href":"https://api.sandbox.paypal.com/v2/payments/captures/something","rel":"self","method":"GET"},{"href":"https://api.sandbox.paypal.com/v2/payments/captures/something/refund","rel":"refund","method":"POST"},{"href":"https://api.sandbox.paypal.com/v2/checkout/orders/something","rel":"up","method":"GET"}],"create_time":"2020-07-28T04:09:05Z","update_time":"2020-07-28T04:09:05Z"}]}}],"links":[{"href":"https://api.sandbox.paypal.com/v2/checkout/orders/something","rel":"self","method":"GET"}],"id":"something","intent":"CAPTURE","payer":{"name":{"given_name":"John","surname":"Doe"},"email_address":"sb-***hidden","payer_id":"something","address":{"country_code":"CA"}},"status":"COMPLETED"},"links":[{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/something","rel":"self","method":"GET"},{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/something/resend","rel":"resend","method":"POST"}]}';

如果我分解结构,它是这样的:

{
"id":"***hidden***",
"event_version":"1.0",
"create_time":"2020-07-28T04:09:33.415Z",
"resource_type":"checkout-order",
"resource_version":"2.0",
"event_type":"CHECKOUT.ORDER.APPROVED",
"summary":"An order has been approved by buyer",
"resource":{
    "update_time":"2020-07-28T04:09:05Z",
    "create_time":"2020-07-28T04:08:53Z",
    "purchase_units":[{
        "reference_id":"default",
        "amount":{
            "currency_code":"CAD",
            "value":"50.00"
        },
        "payee":{
            "email_address":"***hidden***",
            "merchant_id":"***hidden***"},
            "custom_id":"THISISTHEVALUEIWANT",
...

我想提取custom_id的值并将其存储在 php 变量中。问题是我很难找到提取这个特定项目的方法,据我所知,它是一个对象、一个数组、一个对象......

我尝试了多种组合,我尝试了 foreach 循环,到目前为止没有任何效果。

唯一真正起作用的是:

$json = json_decode($jsonobj, true); // json is stored in $jsonobj variable

foreach($json as $elem)  {
   foreach ($elem['purchase_units'] as $item ) {
      echo $item['custom_id'];
   }
}

这让我得到了我想要的值,但同时它给我抛出了一大堆E_WARNING 类型 2 错误

Invalid argument supplied for foreach()...

Illegal string offset 'purchase_units'...

你能告诉我如何在不淹没我的 php 错误日志的情况下达到这个特定值吗?

非常感谢!

标签: phparraysjson

解决方案


以下内容应该适合您。我不得不处理这样一个复杂的对象结构,并且设法非常简单地做到了。

首先,需要注意的是,您提供的原始 JSON 与您基于原始构建的格式化示例不匹配。更具体地说,custom_id不在payee. 相反,它与payee. 它是这样的......

...
"purchase_units": [
  {
    "reference_id": "default",
    "amount": {
      "currency_code": "CAD",
      "value": "50.00"
    },
    "payee": {
      "email_address": "***hidden**",
      "merchant_id": "***hidden***"
    },
    "custom_id": "THISVALUEIWANT",  <--- This is what you need
    "shipping": { ...

我提供的解决方案将基于原始 JSON。

<?php
$json = <<<JSON
{
  "id": "***hidden***",
  "event_version": "1.0",
  "create_time": "2020-07-28T04:09:33.415Z",
  "resource_type": "checkout-order",
  "resource_version": "2.0",
  "event_type": "CHECKOUT.ORDER.APPROVED",
  "summary": "An order has been approved by buyer",
  "resource": {
    "update_time": "2020-07-28T04:09:05Z",
    "create_time": "2020-07-28T04:08:53Z",
    "purchase_units": [
      {
        "reference_id": "default",
        "amount": {
          "currency_code": "CAD",
          "value": "50.00"
        },
        "payee": {
          "email_address": "***hidden**",
          "merchant_id": "***hidden***"
        },
        "custom_id": "THISVALUEIWANT",
        "shipping": {
          "name": {
            "full_name": "John Doe"
          },
          "address": {
            "address_line_1": "1 Maire-Victorin",
            "admin_area_2": "Toronto",
            "admin_area_1": "ON",
            "postal_code": "M5A 1E1",
            "country_code": "CA"
          }
        },
        "payments": {
          "captures": [
            {
              "id": "***hidden***",
              "status": "COMPLETED",
              "amount": {
                "currency_code": "CAD",
                "value": "50.00"
              },
              "final_capture": true,
              "seller_protection": {
                "status": "ELIGIBLE",
                "dispute_categories": [
                  "ITEM_NOT_RECEIVED",
                  "UNAUTHORIZED_TRANSACTION"
                ]
              },
              "seller_receivable_breakdown": {
                "gross_amount": {
                  "currency_code": "CAD",
                  "value": "50.00"
                },
                "paypal_fee": {
                  "currency_code": "CAD",
                  "value": "1.75"
                },
                "net_amount": {
                  "currency_code": "CAD",
                  "value": "48.25"
                }
              },
              "links": [
                {
                  "href": "https://api.sandbox.paypal.com/v2/payments/captures/something",
                  "rel": "self",
                  "method": "GET"
                },
                {
                  "href": "https://api.sandbox.paypal.com/v2/payments/captures/something/refund",
                  "rel": "refund",
                  "method": "POST"
                },
                {
                  "href": "https://api.sandbox.paypal.com/v2/checkout/orders/something",
                  "rel": "up",
                  "method": "GET"
                }
              ],
              "create_time": "2020-07-28T04:09:05Z",
              "update_time": "2020-07-28T04:09:05Z"
            }
          ]
        }
      }
    ],
    "links": [
      {
        "href": "https://api.sandbox.paypal.com/v2/checkout/orders/something",
        "rel": "self",
        "method": "GET"
      }
    ],
    "id": "something",
    "intent": "CAPTURE",
    "payer": {
      "name": {
        "given_name": "John",
        "surname": "Doe"
      },
      "email_address": "sb-***hidden",
      "payer_id": "something",
      "address": {
        "country_code": "CA"
      }
    },
    "status": "COMPLETED"
  },
  "links": [
    {
      "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/something",
      "rel": "self",
      "method": "GET"
    },
    {
      "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/something/resend",
      "rel": "resend",
      "method": "POST"
    }
  ]
}
JSON;

$object = json_decode($json);

$purchase_units = $object->resource->purchase_units ?? [];
$custom_ids = array_column($purchase_units, 'custom_id');

print_r($custom_ids);

输出将是:

Array
(
    [0] => THISVALUEIWANT
)

现在稍微解释一下。解码 JSON 对象后,我直接使用我需要使用的属性$purchase_units = $object->resource->purchase_units ?? [];

如果不存在任何内容,则空合并运算符将允许将$purchase_units变量默认为空数组。$object->resource->purchase_units

array_column函数允许从数组中包含的所有项目中提取特定列或属性。您可以在https://www.php.net/manual/en/function.array-column.php阅读更多相关信息


推荐阅读