dongzhang2150
dongzhang2150
2014-07-09 14:16
浏览 62

使用PHP - Loop从EAN API读取响应JSON

I am trying to build an application that searches through a Response JSON from the Expidia API.

When I use this method it works fine:

<form name="search_form" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
<label><span class="label">Town:</span>
<input type="text" id="search_town" name="search_town"></label>
<br><br><input class="Send" type="submit" name="search" value="Search">
</form>

<?php
if(isset($_POST['search']))
{
    SearchTown();
}

function SearchTown()
{
$search_town = $_POST['search_town'];
$no_requests = "1";

$url    = "http://dev.api.ean.com/ean-services/rs/hotel/v3/list?cid=55505&apiKey=r662e63dr8tkvh9ttqjmsev8&locale=en_US&currencyCode=USD&xml=%3CHotelListRequest%3E%3Ccity%3E".$search_town."%3C/city%3E%3CarrivalDate%3E08/01/2014%3C/arrivalDate%3E%3CdepartureDate%3E08/03/2014%3C/departureDate%3E%3CRoomGroup%3E%3CRoom%3E%3CnumberOfAdults%3E2%3C/numberOfAdults%3E%3C/Room%3E%3C/RoomGroup%3E%3CnumberOfResults%3E".$no_requests."%3C/numberOfResults%3E%3CsupplierCacheTolerance%3EMED_ENHANCED%3C/supplierCacheTolerance%3E%3C/HotelListRequest%3E";
$result = file_get_contents($url);


$data = json_decode($result);

    print_r($data->HotelListResponse->HotelList->HotelSummary->name);
}
?>

It gives me the Hotel in the City I type in. So this works fine

In the URL Request I just searched for 1 reply, but obviously I would like to get back a few Hotels.

I tried this:

<form name="search_form" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
<label><span class="label">Town:</span>
<input type="text" id="search_town" name="search_town"></label>
<br><br><input class="Send" type="submit" name="search" value="Search">
</form>

<?php
if(isset($_POST['search']))
{
    SearchTown();
}

function SearchTown()
{
$search_town = $_POST['search_town'];
$no_requests = "2";

$url    = "http://dev.api.ean.com/ean-services/rs/hotel/v3/list?cid=55505&apiKey=r662e63dr8tkvh9ttqjmsev8&locale=en_US&currencyCode=USD&xml=%3CHotelListRequest%3E%3Ccity%3E".$search_town."%3C/city%3E%3CarrivalDate%3E08/01/2014%3C/arrivalDate%3E%3CdepartureDate%3E08/03/2014%3C/departureDate%3E%3CRoomGroup%3E%3CRoom%3E%3CnumberOfAdults%3E2%3C/numberOfAdults%3E%3C/Room%3E%3C/RoomGroup%3E%3CnumberOfResults%3E".$no_requests."%3C/numberOfResults%3E%3CsupplierCacheTolerance%3EMED_ENHANCED%3C/supplierCacheTolerance%3E%3C/HotelListRequest%3E";
$result = file_get_contents($url);


$data = json_decode($result);

for ($i = 1; $i <= $no_requests; $i++) {
    print_r($data->HotelListResponse->HotelList->HotelSummary->name[$i]);
}
}
?>

It gives me the notice:

Notice: Trying to get property of non-object in C:\xampp\htdocs\vhi_test\testing2.php on line 34

I have tried a million different approaches and just can not seem to get more than ONE name out of the Response. Please, can anybody help? Much much appreciated.

Edit: Here are sample responses for both single and multiple results, respectively.

{"HotelListResponse":{"customerSessionId":"0ABAAAB2-1097-6F91-4712-BDAD2ED90D22","numberOfRoomsRequested":1,"moreResultsAvailable":true,"cacheKey":"-7610976f:1471bdad2ed:-d20","cacheLocation":"10.186.170.178:7300","HotelList":{"@size":"1","@activePropertyCount":"142","HotelSummary":{"@order":"0","hotelId":126952,"name":"Cleveland Marriott Downtown at Key Center","address1":"127 Public Sq","city":"Cleveland","stateProvinceCode":"OH","postalCode":44114,"countryCode":"US","airportCode":"CLE","supplierType":"E","propertyCategory":1,"hotelRating":3.5,"confidenceRating":52,"amenityMask":16818307,"tripAdvisorRating":4.5,"locationDescription":"Near Quicken Loans Arena","shortDescription":"<p><b>Property Location<\\/b> <br \\/>With a stay at Cleveland Marriott Downtown at Key Center, you'll be centrally located in Cleveland, steps from Old Stone Church and Key Tower. This hotel is within","highRate":159,"lowRate":159,"rateCurrencyCode":"USD","latitude":41.50044,"longitude":-81.69424,"proximityDistance":3.4120276,"proximityUnit":"MI","hotelInDestination":true,"thumbNailUrl":"\\/hotels\\/1000000\\/30000\\/23200\\/23199\\/23199_66_t.jpg","deepLink":"http:\\/\\/travel.ian.com\\/index.jsp?pageName=hotAvail&cid=55505&hotelID=126952&mode=2&numberOfRooms=1&room-0-adult-total=2&room-0-child-total=0&arrivalMonth=7&arrivalDay=1&departureMonth=7&departureDay=3&showInfo=true&locale=en_US&currencyCode=USD","RoomRateDetailsList":{"RoomRateDetails":{"roomTypeCode":30940,"rateCode":202960472,"maxRoomOccupancy":4,"quotedRoomOccupancy":2,"minGuestAge":0,"roomDescription":"Deluxe Room - Advance Purchase*","currentAllotment":0,"propertyAvailable":true,"propertyRestricted":false,"expediaPropertyId":23199,"rateKey":"0ABAAAB2-1097-6F91-4712-BDAD2ED90D1F","RateInfo":{"@priceBreakdown":"true","@promo":"false","@rateChange":"false","ChargeableRateInfo":{"@averageBaseRate":"159.0","@averageRate":"159.0","@commissionableUsdTotal":"318.0","@currencyCode":"USD","@maxNightlyRate":"159.0","@nightlyRateTotal":"318.0","@surchargeTotal":"62.1","@total":"380.1","NightlyRatesPerRoom":{"@size":"2","NightlyRate":[{"@baseRate":"159.0","@rate":"159.0","@promo":"false"},{"@baseRate":"159.0","@rate":"159.0","@promo":"false"}]},"Surcharges":{"@size":"1","Surcharge":{"@type":"TaxAndServiceFee","@amount":"62.1"}}}}}}}}}}

{"HotelListResponse":{"customerSessionId":"0ABAAAB0-E70B-AC91-4712-BD8FEE3927B3","numberOfRoomsRequested":1,"moreResultsAvailable":true,"cacheKey":"-5e70bac:1471bd8fee3:27c4","cacheLocation":"10.186.170.176:7300","HotelList":{"@size":"2","@activePropertyCount":"142","HotelSummary":[{"@order":"0","hotelId":126952,"name":"Cleveland Marriott Downtown at Key Center","address1":"127 Public Sq","city":"Cleveland","stateProvinceCode":"OH","postalCode":44114,"countryCode":"US","airportCode":"CLE","supplierType":"E","propertyCategory":1,"hotelRating":3.5,"confidenceRating":52,"amenityMask":16818307,"tripAdvisorRating":4.5,"locationDescription":"Near Quicken Loans Arena","shortDescription":"<p><b>Property Location<\\/b> <br \\/>With a stay at Cleveland Marriott Downtown at Key Center, you'll be centrally located in Cleveland, steps from Old Stone Church and Key Tower. This hotel is within","highRate":159,"lowRate":159,"rateCurrencyCode":"USD","latitude":41.50044,"longitude":-81.69424,"proximityDistance":3.4120276,"proximityUnit":"MI","hotelInDestination":true,"thumbNailUrl":"\\/hotels\\/1000000\\/30000\\/23200\\/23199\\/23199_66_t.jpg","deepLink":"http:\\/\\/travel.ian.com\\/index.jsp?pageName=hotAvail&cid=55505&hotelID=126952&mode=2&numberOfRooms=1&room-0-adult-total=2&room-0-child-total=0&arrivalMonth=7&arrivalDay=1&departureMonth=7&departureDay=3&showInfo=true&locale=en_US&currencyCode=USD","RoomRateDetailsList":{"RoomRateDetails":{"roomTypeCode":30940,"rateCode":202960472,"maxRoomOccupancy":4,"quotedRoomOccupancy":2,"minGuestAge":0,"roomDescription":"Deluxe Room - Advance Purchase*","currentAllotment":0,"propertyAvailable":true,"propertyRestricted":false,"expediaPropertyId":23199,"rateKey":"0ABAAAB0-E70B-AC91-4712-BD8FEE3927C5","RateInfo":{"@priceBreakdown":"true","@promo":"false","@rateChange":"false","ChargeableRateInfo":{"@averageBaseRate":"159.0","@averageRate":"159.0","@commissionableUsdTotal":"318.0","@currencyCode":"USD","@maxNightlyRate":"159.0","@nightlyRateTotal":"318.0","@surchargeTotal":"62.1","@total":"380.1","NightlyRatesPerRoom":{"@size":"2","NightlyRate":[{"@baseRate":"159.0","@rate":"159.0","@promo":"false"},{"@baseRate":"159.0","@rate":"159.0","@promo":"false"}]},"Surcharges":{"@size":"1","Surcharge":{"@type":"TaxAndServiceFee","@amount":"62.1"}}}}}}},{"@order":"1","hotelId":163227,"name":"DoubleTree by Hilton Cleveland Downtown - Lakeside","address1":"1111 Lakeside Avenue E","city":"Cleveland","stateProvinceCode":"OH","postalCode":44114,"countryCode":"US","airportCode":"CLE","supplierType":"E","propertyCategory":1,"hotelRating":3.5,"confidenceRating":52,"amenityMask":24617091,"tripAdvisorRating":4,"locationDescription":"Near Rock and Roll Hall of Fame","shortDescription":"<p><b>Property Location<\\/b> <br \\/>A stay at DoubleTree by Hilton Cleveland Downtown - Lakeside places you in the heart of Cleveland, walking distance from Cleveland Public Auditorium and Rock and","highRate":179.1,"lowRate":179.1,"rateCurrencyCode":"USD","latitude":41.50642,"longitude":-81.69018,"proximityDistance":3.3392038,"proximityUnit":"MI","hotelInDestination":true,"thumbNailUrl":"\\/hotels\\/1000000\\/20000\\/19900\\/19876\\/19876_113_t.jpg","deepLink":"http:\\/\\/travel.ian.com\\/index.jsp?pageName=hotAvail&cid=55505&hotelID=163227&mode=2&numberOfRooms=1&room-0-adult-total=2&room-0-child-total=0&arrivalMonth=7&arrivalDay=1&departureMonth=7&departureDay=3&showInfo=true&locale=en_US&currencyCode=USD","RoomRateDetailsList":{"RoomRateDetails":{"roomTypeCode":345298,"rateCode":1078896,"maxRoomOccupancy":4,"quotedRoomOccupancy":2,"minGuestAge":0,"roomDescription":"Two Queen Beds Non-Smoking","currentAllotment":0,"propertyAvailable":true,"propertyRestricted":false,"expediaPropertyId":19876,"rateKey":"0ABAAAB0-E70B-AC91-4712-BD8FEE3927C6","RateInfo":{"@priceBreakdown":"true","@promo":"false","@rateChange":"false","ChargeableRateInfo":{"@averageBaseRate":"179.1","@averageRate":"179.1","@commissionableUsdTotal":"358.2","@currencyCode":"USD","@maxNightlyRate":"179.1","@nightlyRateTotal":"358.2","@surchargeTotal":"69.64","@total":"427.84","NightlyRatesPerRoom":{"@size":"2","NightlyRate":[{"@baseRate":"179.1","@rate":"179.1","@promo":"false"},{"@baseRate":"179.1","@rate":"179.1","@promo":"false"}]},"Surcharges":{"@size":"1","Surcharge":{"@type":"TaxAndServiceFee","@amount":"69.64"}}}},"ValueAdds":{"@size":"1","ValueAdd":{"@id":"2048","description":"Free Wireless Internet"}}}}}]}}}
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • doushang2571
    doushang2571 2014-07-09 17:59
    已采纳

    The main issue here is that you're trying to access the name property as an array instead of HotelSummary. Additionally, HotelSummary is only returned as an array if there is more than one result, otherwise it's an object. This is solved by conditionally wrapping it before the loop.

    The index variable $i in your for loop is initialized to 1, but 0 is the first element of an array. Likewise, you would have wanted to have the condition as $i < $no_requests;. I replaced that with a foreach loop where you don't have to worry about managing the index.

    <form name="search_form" action="" method="POST">
        <label>
            <span class="label">Town:</span>
            <input type="text" id="search_town" name="search_town" />
        </label><br />
        <br />
        <input class="Send" type="submit" name="search" value="Search" />
    </form>
    
    <?php
    if(isset($_POST["search"]))
    {
        SearchTown();
    }
    
    function SearchTown()
    {
        $search_town = $_POST["search_town"];
        $no_requests = 2;
    
        $url = "http://dev.api.ean.com/ean-services/rs/hotel/v3/list?cid=55505&apiKey=r662e63dr8tkvh9ttqjmsev8&locale=en_US&currencyCode=USD&xml=%3CHotelListRequest%3E%3Ccity%3E".$search_town."%3C/city%3E%3CarrivalDate%3E08/01/2014%3C/arrivalDate%3E%3CdepartureDate%3E08/03/2014%3C/departureDate%3E%3CRoomGroup%3E%3CRoom%3E%3CnumberOfAdults%3E2%3C/numberOfAdults%3E%3C/Room%3E%3C/RoomGroup%3E%3CnumberOfResults%3E".$no_requests."%3C/numberOfResults%3E%3CsupplierCacheTolerance%3EMED_ENHANCED%3C/supplierCacheTolerance%3E%3C/HotelListRequest%3E";
        $result = file_get_contents($url);
    
    
        $data = json_decode($result);
    
        // Make sure HotelSummary is an array - a single result does not get an array wrapper in the response.
        if (!is_array($data->HotelListResponse->HotelList->HotelSummary))
            // A simple cast using (array) won't work here - it would convert the HotelSummary object itself rather than wrapping it inside of an array.
            $data->HotelListResponse->HotelList->HotelSummary = array($data->HotelListResponse->HotelList->HotelSummary);
    
        foreach ($data->HotelListResponse->HotelList->HotelSummary as $i => $hotelSummary)
        {
            echo "{$i}: " . $hotelSummary->name . "<br />";
        }
    }
    

    When searching for Cleveland while $no_requests is set to 2, the result is:

    0: Cleveland Marriott Downtown at Key Center
    1: DoubleTree by Hilton Cleveland Downtown - Lakeside
    

    Performing the same search after reducing $no_requests to 1 results in:

    0: Cleveland Marriott Downtown at Key Center
    
    点赞 评论

相关推荐