从更深层的嵌套多维数组中获取值

时间:2018-10-29 07:42:25

标签: php json laravel multidimensional-array

我有以下json_decode($ array,true);多家酒店的数据。

array: 10[▼
    "HotelName" => "AL MANZIL DOWNTOWN DUBAI"
    "PreferredStatus" => "A"
    "PropertyType" => "City Hotel"
    "StarRating" => "4"
    "GeoLocation" => array: 2[▶]
    "Chain" => "ADDRESS HOTELS"
    "HotelCode" => "32-4560"
    "HotelDescr" => []
    "Zone" => "Downtown"
    "RoomTypeDetails" => array: 1[▼
      "Rooms" => array: 1[▼
        "Room" => array: 18[▼
          0 => array: 23[▼
            "RoomNo" => "1"
            "RoomType" => "DELUXE ROOM"
            "RoomTypeCode" => "14264"
            "RoomStatus" => "OK"
            "BlackOut" => array: 2[▶]
            "CurrCode" => "AED"
            "ContractTokenId" => "191032"
            "RoomConfigurationId" => "1"
            "DynamicInventory" => "N"
            "ContractLabel" => []
            "Refundable" => "Y"
            "PackageYN" => "N"
            "MealPlan" => "ROOM ONLY"
            "MealPlanCode" => "1380"
            "RoomNumber" => "1"
            "BuyRate" => []
            "CommissionSellCharges" => []
            "TaxSellCharges" => []
            "Rate" => "3430.4"
            "RoomStatusDetails" => array: 1[▶]
            "SupplementDetails" => array:1 [▼
              "Supplement" => array:12 [▼
                 "Id" => "403880"
                 "FromDate" => "20191015"
                 "ToDate" => "20191018"
                 "Qty" => "1"
                 "Rate" => "127"
                 "CommissionSellCharges" => []
                 "TaxSellCharges" => []
                 "BuyRate" => []
                 "Name" => "CHILD SUPPLEMENT"
                 "OptionalYN" => "N"
                 "ValidOn" => "YYYYYYY"
                 "Nights" => "4"
               ]
             ]
            "DiscountDetails" => array: 1[▼
              "Discount" => array: 8[▼
                "DiscountName" => "EARLY BIRD OFFER 2019-2020  20 % DISCOUNT"
                "DiscountType" => "Price Reduction Discount"
                "DiscountNotes" => "<html><body><p><strong>EARLY BIRD OFFER 2019 - 2020 | 20% DISCOUNT <br /><br />Terms and Conditions:</strong> <br />- Applicable for all booking received&nbsp;6 ▶"
                "DiscountTypeCode" => "0"
                "TotalDiscountRate" => "857.6"
                "CommissionSellCharges" => []
                "TaxSellCharges" => []
                "TotalDiscountBuyRate" => []
              ]
            ]
            "PromotionalContract" => "N"
          ] 1 => array: 23[▼
            "RoomNo" => "1"
            "RoomType" => "DELUXE ROOM"
            "RoomTypeCode" => "14264"
            "RoomStatus" => "OK"
            "BlackOut" => array: 2[▶]
            "CurrCode" => "AED"
            "ContractTokenId" => "191032"
            "RoomConfigurationId" => "1"
            "DynamicInventory" => "N"
            "ContractLabel" => []
            "Refundable" => "Y"
            "PackageYN" => "N"
            "MealPlan" => "BED AND BREAKFAST"
            "MealPlanCode" => "1376"
            "RoomNumber" => "1"
            "BuyRate" => []
            "CommissionSellCharges" => []
            "TaxSellCharges" => []
            "Rate" => "4019.2"
            "RoomStatusDetails" => array: 1[▶]
            "SupplementDetails" => array: 1[▶]
            "DiscountDetails" => array: 1[▶]
            "PromotionalContract" => "N"
          ]

我可以使用foreach循环来获取特定酒店的值,例如以下代码

//All the hotel names
@foreach ($array['Hotels']['Hotel'] as $key => $hotel){

echo $hotel['HotelName']; //Displays all the hotel names
}

// All the RoomTypes of a single hotel array
@foreach ($hotel['RoomTypeDetails']['Rooms']['Room'] as $k => $rt {

  echo $rt['RoomType'];  //Displays all the RoomTypes of a hotel
}

//I would like to get the discounts of a single room type of a hotel
@foreach ($rt['DiscountDetails'] as $d { 

  echo $d['DiscountName'] // NOT WORKING - Throws error, Undefined index - 
  NEED HELP HERE
}

//I would like to get the supplements of a single room type of a hotel
@foreach ($rt['SupplementDetails']['Supplement'] as $s { 

  echo $s['Name'] // NOT WORKING - Throws error, Undefined Index - NEED HELP  
  HERE
}

我正在使用laravel框架v5.7进行开发,这些数据是通过远程API进行的XML响应,经json解码后可以在我的应用中使用。我一直在尝试找出如何在多维数组中回显数组中更深层嵌套的元素。

我想从上面的json输出数据中获取以下值的层次结构。

  1. 酒店>客房>房价(折扣)
  2. 酒店>客房>补品

我搜索了堆栈溢出和其他论坛,也发现了一些方案和可能的解决方案,也应用了一些方案,但似乎没有显示我需要的值。

尝试嵌套每个功能仍然无法正常工作。如果您对这些种类的数据有任何经验,请给我帮助或指导我以获得与更深层嵌套的多维数组配合使用的最佳实践。

如果想知道这里是$ rt变量的转储[它已经在单个hotel元素中了]

array: 23[▼
  "RoomNo" => "1"
  "RoomType" => "DELUXE ROOM"
  "RoomTypeCode" => "14264"
  "RoomStatus" => "OK"
  "BlackOut" => array: 2[▶]
  "CurrCode" => "AED"
  "ContractTokenId" => "191032"
  "RoomConfigurationId" => "1"
  "DynamicInventory" => "N"
  "ContractLabel" => []
  "Refundable" => "Y"
  "PackageYN" => "N"
  "MealPlan" => "ROOM ONLY"
  "MealPlanCode" => "1380"
  "RoomNumber" => "1"
  "BuyRate" => []
  "CommissionSellCharges" => []
  "TaxSellCharges" => []
  "Rate" => "3430.4"
  "RoomStatusDetails" => array: 1[▶]
  "SupplementDetails" => array: 1[▼
    "Supplement" => array: 12[▼
      "Id" => "403880"
      "FromDate" => "20191015"
      "ToDate" => "20191018"
      "Qty" => "1"
      "Rate" => "127"
      "CommissionSellCharges" => []
      "TaxSellCharges" => []
      "BuyRate" => []
      "Name" => "CHILD SUPPLEMENT"
      "OptionalYN" => "N"
      "ValidOn" => "YYYYYYY"
      "Nights" => "4"
    ]
  ]
  "DiscountDetails" => array: 1[▼
    "Discount" => array: 8[▼
      "DiscountName" => "EARLY BIRD OFFER 2019-2020  20 % DISCOUNT"
      "DiscountType" => "Price Reduction Discount"
      "DiscountNotes" => "<html><body><p><strong>EARLY BIRD OFFER 2019 - 2020 | 20% DISCOUNT <br /><br />Terms and Conditions:</strong> <br />- Applicable for all booking received&nbsp;6 ▶"
      "DiscountTypeCode" => "0"
      "TotalDiscountRate" => "857.6"
      "CommissionSellCharges" => []
      "TaxSellCharges" => []
      "TotalDiscountBuyRate" => []
    ]
  ]
  "PromotionalContract" => "N"
]

非常感谢! 艾萨尔(Aisar)

3 个答案:

答案 0 :(得分:0)

尝试一下。获得一些价值不需要循环。

//All the hotel names
@foreach ($array['Hotels']['Hotel'] as $key => $hotel){

    echo $hotel['HotelName']; //Displays all the hotel names

    // All the RoomTypes of a single hotel array
    @foreach ($hotel['RoomTypeDetails']['Rooms']['Room'] as $k => $rt {

      echo $rt['RoomType'];  //Displays all the RoomTypes of a hotel


      //I would like to get the discounts of a single room type of a hotel
      if(isset($rt['DiscountDetails']['Discount']['DiscountName']))
          echo $rt['DiscountDetails']['Discount']['DiscountName'];
      else
          echo 'No discount';

      //I would like to get the supplements of a single room type of a hotel
      if(isset($rt['SupplementDetails']['Supplement']['Name']))
          echo $rt['SupplementDetails']['Supplement']['Name'];
      else
          echo 'No Supplement';

    }
}

答案 1 :(得分:0)

据我所知,您忘记了代码的某些部分,索引

@foreach ($rt['RoomTypeDetails']['Rooms']['Room']['DiscountDetails'] as $d { 

  echo $d['DiscountName'];
}


@foreach ($rt['RoomTypeDetails']['Rooms']['Room']['SupplementDetails']['Supplement'] as $s { 

  echo $s['Name'];
}

答案 2 :(得分:0)

您可以使用Laravel辅助函数,例如data_get(),甚至可以使用get()pluck()等集合函数来处理 Arrayable 项目。

让我们以data_get()为例,使用此路径MealPlan获取所有RoomTypeDetails->Rooms->Room->*-> MealPlan

$data = [
            "HotelName" => "AL MANZIL DOWNTOWN DUBAI",
            "PreferredStatus" => "A",
            "PropertyType" => "City Hotel",
            "StarRating" => "4",
            "GeoLocation" => [],
            "Chain" => "ADDRESS HOTELS",
            "HotelCode" => "32-4560",
            "HotelDescr" => [],
            "Zone" => "Downtown",
            "RoomTypeDetails" => [
                "Rooms" => [
                    "Room" => [
                        0 => [
                            "RoomNo" => "1",
                            "RoomType" => "DELUXE ROOM",
                            "RoomTypeCode" => "14264",
                            "RoomStatus" => "OK",
                            "BlackOut" => [],
                            "CurrCode" => "AED",
                            "ContractTokenId" => "191032",
                            "RoomConfigurationId" => "1",
                            "DynamicInventory" => "N",
                            "ContractLabel" => [],
                            "Refundable" => "Y",
                            "PackageYN" => "N",
                            "MealPlan" => "ROOM ONLY",
                            "MealPlanCode" => "1380",
                            "RoomNumber" => "1",
                            "BuyRate" => [],
                            "CommissionSellCharges" => [],
                            "TaxSellCharges" => [],
                            "Rate" => "3430.4",
                            "RoomStatusDetails" => [],
                            "SupplementDetails" => [
                                "Supplement" => [
                                    "Id" => "403880",
                                    "FromDate" => "20191015",
                                    "ToDate" => "20191018",
                                    "Qty" => "1",
                                    "Rate" => "127",
                                    "CommissionSellCharges" => [],
                                    "TaxSellCharges" => [],
                                    "BuyRate" => [],
                                    "Name" => "CHILD SUPPLEMENT",
                                    "OptionalYN" => "N",
                                    "ValidOn" => "YYYYYYY",
                                    "Nights" => "4",
                                ]
                            ],
                            "DiscountDetails" => [
                                "Discount" => [
                                    "DiscountName" => "EARLY BIRD OFFER 2019-2020  20 % DISCOUNT",
                                    "DiscountType" => "Price Reduction Discount",
                                    "DiscountNotes" => "<html><body><p><strong>EARLY BIRD OFFER 2019 - 2020 | 20% DISCOUNT <br /><br />Terms and Conditions:</strong> <br />- Applicable for all booking received&nbsp;6 ",
                                    "DiscountTypeCode" => "0",
                                    "TotalDiscountRate" => "857.6",
                                    "CommissionSellCharges" => [],
                                    "TaxSellCharges" => [],
                                    "TotalDiscountBuyRate" => [],
                                ],
                            ],
                            "PromotionalContract" => "N",
                        ], 1 => [
                            "RoomNo" => "1",
                            "RoomType" => "DELUXE ROOM",
                            "RoomTypeCode" => "14264",
                            "RoomStatus" => "OK",
                            "BlackOut" => [],
                            "CurrCode" => "AED",
                            "ContractTokenId" => "191032",
                            "RoomConfigurationId" => "1",
                            "DynamicInventory" => "N",
                            "ContractLabel" => [],
                            "Refundable" => "Y",
                            "PackageYN" => "N",
                            "MealPlan" => "BED AND BREAKFAST",
                            "MealPlanCode" => "1376",
                            "RoomNumber" => "1",
                            "BuyRate" => [],
                            "CommissionSellCharges" => [],
                            "TaxSellCharges" => [],
                            "Rate" => "4019.2",
                            "RoomStatusDetails" => [],
                            "SupplementDetails" => [],
                            "DiscountDetails" => [],
                            "PromotionalContract" => "N",
                        ],
                    ]
                ]
            ]
        ];

        return data_get($data,'RoomTypeDetails.Rooms.Room.*.MealPlan');

这将为您提供:

[
"ROOM ONLY",
"BED AND BREAKFAST"
]

更新

就像@simonecosci提到的使用“点”表示法获取单个值一样,您可以使用array_get,以便拥有:

array_get($data,'RoomTypeDetails.Rooms.Room.1.MealPlan')

除了避免使用foreach之外,使用此方法的优势在于,当数组中不存在属性/索引时,它会返回null