如何读取PHP多层嵌套对象属性 解决MercadoPago嵌套值读取问题
MercadoPago支付对象嵌套属性读取方案
背景
从webhook获取到的支付返回数据结构如下:
{ "id": 1, "date_created": "2017-08-31T11:26:38.000Z", "date_approved": "2017-08-31T11:26:38.000Z", "date_last_updated": "2017-08-31T11:26:38.000Z", "money_release_date": "2017-09-14T11:26:38.000Z", "payment_method_id": "account_money", "payment_type_id": "credit_card", "status": "approved", "status_detail": "accredited", "currency_id": "BRL", "description": "Pago Pizza", "collector_id": 2, "payer": { "id": 123, "email": "afriend@gmail.com", "identification": { "type": "DNI", "number": 12345678 }, "type": "customer" }, "metadata": {}, "additional_info": {}, "transaction_amount": 250, "transaction_amount_refunded": 0, "coupon_amount": 0, "transaction_details": { "net_received_amount": 250, "total_paid_amount": 250, "overpaid_amount": 0, "installment_amount": 250 }, "installments": 1, "card": {} }
获取支付对象的代码如下:
$payment = null; $payment = MercadoPago\Payment::find_by_id($_GET["data_id"]);
当前可正常读取顶层属性,示例代码:
$pStatus = $payment->status; $payID = $payment->id;
直接调用无参toArray()后,通过$responseArray['payer']['email']读取嵌套属性的方式无法生效,可通过以下方案解决。
可行解决方案
方案1:链式对象属性读取(推荐)
MercadoPago官方PHP SDK返回的嵌套节点本身为实例化对象,无需转数组,直接通过->操作符链式读取即可:
// 读取payer层级的邮箱字段 $payerEmail = $payment->payer->email; // 读取更深层的用户证件号 $payerIdNumber = $payment->payer->identification->number; // 读取交易详情下的实际到账金额 $netReceived = $payment->transaction_details->net_received_amount;
读取前建议通过isset()判断属性是否存在,避免节点缺失时抛出错误,示例:$payerEmail = isset($payment->payer->email) ? $payment->payer->email : '';
方案2:递归转数组后读取
如果需要使用数组格式操作数据,无参调用toArray()只会转换顶层属性,需要传入递归参数开启全量转换:
// 传入true开启递归转换,所有嵌套节点都会转为数组格式 $responseArray = $payment->toArray(true); // 正常通过数组下标读取即可 $payerEmail = $responseArray['payer']['email']; $payerIdType = $responseArray['payer']['identification']['type'];
如果当前SDK版本的toArray()不支持递归参数,可通过JSON编解码实现兼容转换,适配所有版本:
$responseArray = json_decode(json_encode($payment), true); $payerEmail = $responseArray['payer']['email'];
常见失效原因排查
- 调用
toArray()时未传递归参数:默认方法仅转换顶层属性,嵌套节点仍为对象格式,直接用数组下标读取会报错 - SDK版本过低:旧版本SDK存在嵌套属性映射bug,升级到最新稳定版即可修复
- 目标节点本身为空:比如示例数据中
card字段为空对象,读取该节点下的属性会返回null,需要提前做判空处理
内容的提问来源于stack exchange,提问作者Paulo Borges
相关产品推荐
相关产品推荐

