PHP将嵌套对象数组转为指定格式JSON的问题求助
问题解决:将FattureInCloud文档项转换为指定JSON结构
问题背景
需要将包含FattureInCloud\Model\ReceivedDocumentItemsListItem对象的items_list数组,转换为指定结构的JSON,但现有循环仅返回最后一组数据。
原数据结构
[items_list] => Array ( [0] => FattureInCloud\Model\ReceivedDocumentItemsListItem Object ( [openAPINullablesSetToNull:protected] => Array ( [0] => product_id ) [container:protected] => Array ( [id] => 317193954 [product_id] => [code] => [name] => Gestione pratica [measure] => [net_price] => 0.6 [category] => [qty] => 1 [vat] => Fatture\Model\VatType Object ( [container:protected] => Array ( [id] => 2531827 [value] => 22 [description] => 22%-GENERICO [notes] => [e_invoice] => [ei_type] => [ei_description] => [editable] => [is_disabled] => ) ) [stock] => 0 ) ) )
目标JSON结构
"lines": [ { "desc": "Some additional text", "qty": "10", "subprice": 100, "tva_tx": "20.000", "fk_product": "1", "remise_percent": "0", "date_start": 1494252128, "date_end": 1494194400, "info_bits": "0" } ],
错误代码
foreach($result['items_list'] as $item) { $myObj->lines = new stdClass; $myObj->lines->desc = $item['name']; $myObj->lines->qty = $item['qty']; $myObj->lines->subprice = $item['net_price']; }
问题分析与修正
1. 循环覆盖问题
循环中每次都将$myObj->lines重新赋值为新对象,导致之前的数据被覆盖,最终仅保留最后一条。正确做法是先将$myObj->lines初始化为数组,循环时往数组中追加对象。
2. 对象属性访问问题
原数据是ReceivedDocumentItemsListItem对象,内部container属性为受保护状态,无法直接通过$item['name']访问。需通过SDK提供的Getter方法,或反射获取受保护属性。
修正后的代码
方式一:使用SDK Getter方法(推荐)
// 初始化lines为数组 $myObj->lines = []; foreach($result['items_list'] as $item) { $line = new stdClass(); // 调用Model类的Getter方法获取属性 $line->desc = $item->getName(); $line->qty = (string)$item->getQty(); // 匹配目标结构的字符串格式 $line->subprice = (float)$item->getNetPrice(); // 处理VAT税率,格式化为三位小数的字符串 $vat = $item->getVat(); $line->tva_tx = number_format($vat->getValue(), 3); // 填充目标结构的其他字段 $line->fk_product = $item->getProductId() ?? ''; $line->remise_percent = "0"; $line->date_start = 0; // 可根据实际需求调整默认值 $line->date_end = 0; $line->info_bits = "0"; // 将当前行追加到lines数组 $myObj->lines[] = $line; } // 转换为目标JSON $jsonResult = json_encode($myObj);
方式二:反射获取受保护属性(无Getter方法时使用)
// 自定义方法获取对象的受保护属性 function getProtectedProperty($object, $propertyName) { $reflection = new ReflectionClass($object); $property = $reflection->getProperty($propertyName); $property->setAccessible(true); return $property->getValue($object); } $myObj->lines = []; foreach($result['items_list'] as $item) { // 获取文档项的受保护container属性 $container = getProtectedProperty($item, 'container'); // 获取VAT对象的受保护container属性 $vatContainer = getProtectedProperty($container['vat'], 'container'); $line = new stdClass(); $line->desc = $container['name']; $line->qty = (string)$container['qty']; $line->subprice = (float)$container['net_price']; $line->tva_tx = number_format($vatContainer['value'], 3); // 填充其他字段 $line->fk_product = $container['product_id'] ?? ''; $line->remise_percent = "0"; $line->date_start = 0; $line->date_end = 0; $line->info_bits = "0"; $myObj->lines[] = $line; } $jsonResult = json_encode($myObj);
内容的提问来源于stack exchange,提问作者Dario B.
相关产品推荐
相关产品推荐

