PHP多维数组条件清理优化:替代嵌套foreach的高效方案
问题
我开发了一个程序,把JSON转换为PHP数组后,通过嵌套foreach循环遍历多维数组,删除值为0、空字符串、null或**"Api "**的键值对,最后再转回JSON。但嵌套循环代码冗余,没法适配层级更多的多维数组,想找更简洁的实现方案。
示例JSON
{ "UniqueId": "PO3589472", "FareType": 2, "BookedBy": "Api ", "OrderBy": "Api ", "ClientBalance": 0, "Error": null, "Success": true, "TktTimeLimit": "2022-08-10T14:11:45", "Category": 21, "Status": 21, "RefundMethod": 1, "TravelItinerary": { "ItineraryInfo": { "ItineraryPricing": { "BaseFare": 8469250, "ServiceTax": 0, "TotalTax": 993000, "TotalFare": 9462250, "TotalCommission": 0, "Currency": "IRR" }, "CustomerInfoes": [ { "Customer": { "Gender": 0, "PassengerType": 1, "PassportNumber": "", "NationalId": "1829961233", "Nationality": "IR", "DateOfBirth": "1996-07-08T00:00:00", "PassportExpireDate": "0001-01-01T00:00:00", "PassportIssueCountry": "IR", "PassportIssueDate": "2022-08-10T00:00:00", "PaxName": { "PassengerFirstName": "MAJID", "PassengerMiddleName": null, "PassengerLastName": "MAJIDIFAR", "PassengerTitle": 0 } }, "ETickets": "8151405444745", "ETicketNumbers": [ { "ETicketNumber": "8151405444745", "EticketStatus": 1, "IsRefunded": false, "DateOfIssue": "2022-08-10T13:58:47", "AirlinePnr": "TXNXM", "TotalRefund": 0 } ] } ], "ReservationItems": [ { "AirEquipmentType": "737", "AirlinePnr": "TXNXM", "ArrivalAirportLocationCode": "ABD", "ArrivalDateTime": "2022-08-17T23:25:00", "ArrivalTerminal": "", "Baggage": "20KG", "DepartureAirportLocationCode": "THR", "DepartureDateTime": "2022-08-17T22:05:00", "DepartureTerminal": "Terminal 4", "FlightNumber": "3750", "JourneyDuration": "01:20", "JourneyDurationPerMinute": 0, "MarketingAirlineCode": "EP", "OperatingAirlineCode": "EP", "ResBookDesigCode": "Y", "StopQuantity": 0, "IsCharter": false, "TechnicalStops": [], "IsReturn": false, "CabinClassCode": 1 } ], "TripDetailPtcFareBreakdowns": [ { "PassengerTypeQuantity": { "PassengerType": 1, "Quantity": 1 }, "TripDetailPassengerFare": { "BaseFare": 8469250, "ServiceTax": 0, "Tax": 993000, "TotalFare": 9462250, "Commission": 0, "Currency": "IRR" } } ], "PhoneNumber": "09359276735", "Email": "info@iran-tech.com", "ItineraryFareFamily": null }, "BookingNotes": [], "Services": [] }, "ValidatingAirlineCode": "EP", "DirectionInd": 1, "OnlineCheckIn": false, "AirRemark": [], "curl_error": false }
当前嵌套foreach代码
<?php $jsondata = file_get_contents("test_php.json"); $json = json_decode($jsondata, true); foreach($json as $keys1 => $values1){ if($values1 == 0 || $values1 == "" || $values1 == "Api " || !isset($values1) ){ unset($json[$keys1]); }else{ if(is_array($values1)){ foreach($values1 as $keys2 => $values2){ if($values2 == 0 || $values2 == "" || $values2 == "Api " || !isset($values2) ){ unset($json[$keys1][$keys2]); }else{ if(is_array($values2)){ foreach($values2 as $keys3 => $values3){ if($values3 == 0 || $values3 == "" || $values3 == "Api " || !isset($values3) ){ unset($json[$keys1][$keys2][$keys3]); }else{ if(is_array($values3)){ foreach($values3 as $keys4 => $values4){ if($values4 == 0 || $values4 == "" || $values4 == "Api " || !isset($values4) ){ unset($json[$keys1][$keys2][$keys3][$keys4]); }else{ if(is_array($values4)){ foreach($values4 as $keys5 => $values5){ if($values5 == 0 || $values5 == "" || $values5 == "Api " || !isset($values5) ){ unset($json[$keys1][$keys2][$keys3][$keys4][$keys5]); }else{ if(is_array($values5)){ foreach($values5 as $keys6 => $values6){ if($values6 == 0 || $values6 == "" || $values6 == "Api " || !isset($values6) ){ unset($json[$keys1][$keys2][$keys3][$keys4][$keys5][$keys6]); }else{ if(is_array($values6)){ foreach($values6 as $keys7 => $values7){ if($values7 == 0 || $values7 == "" || $values7 == "Api " || !isset($values7) ){ unset($json[$keys1][$keys2][$keys3][$keys4][$keys5][$keys6][$keys7]); } } } } } } } } } } } } } } } } } } } } $path = "test_php(final).json"; $converter = json_encode($json, JSON_PRETTY_PRINT); $open = fopen($path, 'w'); fwrite($open, $converter); fclose($open); ?>
解决方案
用递归函数就能彻底解决嵌套循环的冗余问题,递归可以自动遍历任意层级的多维数组,不需要手动写多层foreach。核心思路是:遍历数组的每个元素,判断是否需要保留;如果元素是数组,就递归处理这个子数组,再判断处理后的子数组是否需要保留(比如空数组是否要移除,可按需调整)。
实现代码
<?php // 定义递归过滤函数 function filterArray($array) { foreach ($array as $key => $value) { // 判断当前值是否需要移除 if ($value === 0 || $value === "" || $value === "Api " || $value === null) { unset($array[$key]); } elseif (is_array($value)) { // 递归处理子数组 $array[$key] = filterArray($value); // 可选:如果处理后的子数组为空,也移除该键(按需开启) // if (empty($array[$key])) { // unset($array[$key]); // } } } return $array; } // 读取JSON文件并转换为数组 $jsondata = file_get_contents("test_php.json"); $jsonArray = json_decode($jsondata, true); // 执行过滤 $filteredArray = filterArray($jsonArray); // 转换回JSON并保存 $path = "test_php(final).json"; $converter = json_encode($filteredArray, JSON_PRETTY_PRINT); file_put_contents($path, $converter); ?>
代码说明
- 递归函数
filterArray:- 遍历数组的每个键值对,先判断值是否属于要删除的范围(
0、空字符串、"Api "、null),是则直接移除。 - 如果值是数组,就递归调用自身处理这个子数组,处理后替换原数组中的子数组。
- 可选:如果处理后的子数组为空(比如原数据中的
BookingNotes),可以选择移除这个键,只需要取消注释对应的判断代码即可。
- 遍历数组的每个键值对,先判断值是否属于要删除的范围(
- 简化IO操作:用
file_put_contents替代fopen/fwrite/fclose,代码更简洁。 - 兼容性:不管数组有多少层级,递归函数都能自动处理,完全解决嵌套foreach的冗余问题。
内容的提问来源于stack exchange,提问作者mahmoudkhani
相关产品推荐
相关产品推荐

