dongzhang2150 2014-07-09 14:16
浏览 64
已采纳

使用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 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
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序