PHPで空き室のあるホテルを検索する

(1/1)
PHPで最寄りのネットができるホテルを検索する」ではネットができるホテルを検索したが、今回は、「楽天トラベル空室検索API」を利用し、入力された住所または地図の中心の近く(半径2km以内)にあり、指定チェックイン日、チェックアウト日に空いているホテルを地図上にマッピングするプログラムを作ってみる。チェックイン日、チェックアウト日の指定は祝祭日表記付きのカレンダーから入力できるようにし、地図上にホテルの位置をマッピングする。ホテルの画像や住所、電話番号をポップアップウィンドウで表示できるようにする。

(2025年12月6日)PHP8.5対応:double→float表記変更,curl_closeを実行しないようにした
(2025年8月14日).pahooEnv導入, 日本測地系にデグレード,datepickerに祝祭日を表示
(2025年6月14日)GoogleMaps JavaScript APIの変更に対応した.

目次

サンプル・プログラムの実行例

PHPで空き室のあるホテルを検索する
Googleマップ表示

サンプル・プログラム

圧縮ファイルの内容
searchOutlet.phpサンプル・プログラム本体
.pahooEnvクラウドサービスを利用するためのアカウント情報などを記入する .env ファイル。
使い方は「各種クラウド連携サービス(WebAPI)の登録方法」を参照。include_path が通ったディレクトリに配置すること。
pahooInputData.phpデータ入力に関わる関数群。
使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。
pahooGeoCode.php住所・緯度・経度に関わるクラス pahooGeoCode。
使い方は「PHPで住所・ランドマークから最寄り駅を求める」「PHPで住所・ランドマークから緯度・経度を求める」などを参照。include_path が通ったディレクトリに配置すること。
pahooRakuten.php楽天ウェブサービスに関わるクラス pahooRakuten。
使い方は「PHPで最寄りのネットができるホテルを検索する」などを参照。include_path が通ったディレクトリに配置すること。
pahooCalendar.php暦・潮位計算クラス pahooCalendar。
暦・潮位計算クラスの使い方は「PHPで二十四節気・七十二候一覧を作成」「PHPで月齢を計算」「PHPで日出没・月出没・月齢・潮を計算」「PHPで潮位を計算する」などを参照。include_path が通ったディレクトリに配置すること。
searchLibrary.php 更新履歴
バージョン 更新日 内容
2.6.0 2025/08/14 .pahooEnv導入
2.5.0 2023/07/16 検索キーの最小・最大長の指定
2.4.0 2023/07/16 国土地理院ジオコーディングAPIを追加
2.3 2021/10/17 PHP8対応,リファラ・チェック改良
2.2 2020/04/04 OSM Nominatim Search API追加
pahooRakuten.php 更新履歴
バージョン 更新日 内容
3.6.4 2025/11/29 PHP8.5対応:curl_closeを実行しないようにした
3.6.3 2025/08/14 searchVacantHotelsURL() 日本測地系にデグレード
3.6.2 2023/07/09 bug-fix
3.6.1 2022/12/13 PHP8.2対応
3.6 2022/02/05 楽天商品検索API (version:2017-07-06)に変更
pahooGeoCode.php 更新履歴
バージョン 更新日 内容
6.9.1 2025/11/25 PHP8.5対応:double→float
6.9.0 2025/09/21 jsPolygon, jsPolygon_Gmap, jsPolygon_Leaflet, loadGeoJSON, getPrefBorderList を追加
6.8.0 2025/08/10 アクセスキーなどを ".pahooEnd" に分離
6.7.1 2025/07/26 jsLine_Gmap() - bug-fix
6.7.0 2025/07/20 drawJSmap,drawGMap -- 引数 $markerLevel 追加
pahooInputData.php 更新履歴
バージョン 更新日 内容
2.0.1 2025/08/11 getParam() bug-fix
2.0.0 2025/08/11 pahooLoadEnv() 追加
1.9.0 2025/07/26 getParam() 引数に$trim追加
1.8.1 2025/03/15 validRegexPattern() debug
1.8.0 2024/11/12 validRegexPattern() 追加
pahooCalendar.php 更新履歴
バージョン 更新日 内容
4.6.1 2025/11/23 next_fullmoon: bug-fix
4.6.0 2025/10/08 getMidAutumnMoon() 追加
4.5.1 2025/05/31 deg2ddmm(), deg2hhmm() 不具合修正
4.5.0 2024/03/17 ヒジュラ暦メソッドを追加
4.4.1 2024/03/17 getCabinetOfficeHolidayTable() -- bug-fix

サンプル・プログラムの流れ

PHPで空き室のあるホテルを検索する
プログラムの流れは「PHPで最寄りのネットができるホテルを検索する」の時とほぼ同じである。

準備:PHP の https対応

クラウド連携や相手先サイトのデータを読み込むのに https通信を使うため、PHPに OpenSSLモジュールが組み込まれている必要がある。関数  phpinfo  を使って、下図のように表示されればOKだ。
OpenSSL - PHP
そうでない場合は、次の手順に従ってOpenSSLを有効化し、PHPを再起動させる必要がある。

Windowsでは、"php.ini" の下記の行を有効化する。
extension=php_openssl.dll
Linuxでは --with-openssl=/usr オプションを付けて再ビルドする。→OpenSSLインストール手順

これで準備は完了だ。

準備:pahooInputData 関数群

PHPのバージョンや入力データのバリデーションなど、汎用的に使う関数群を収めたファイル "pahooInputData.php" が同梱されているが、include_path が通ったディレクトリに配置してほしい。他のプログラムでも "pahooInputData.php" を利用するが、常に最新のファイルを1つ配置すればよい。

また、各種クラウドサービスに登録したときに取得するアカウント情報、アプリケーションパスワードなどを登録した .pahooEnv ファイルから読み込む関数 pahooLoadEnv を備えている。こちらについては、「各種クラウド連携サービス(WebAPI)の登録方法」をご覧いただきたい。

準備:pahooCalendar クラス

pahooCalendar.php

  11: class pahooCalendar {
  12:     var $CONVERGE = 0.00005;            // 逐次近似計算収束判定値
  13:     var $ASTRO_REFRACT = 0.585556;      // 大気差
  14:     var $TDIFF = +9.0;          // 世界時との時差
  15:     var $error, $errmsg;        // エラーフラグ,エラーメッセージ
  16:     var $year, $month, $day;    // 西暦年月日
  17:     var $tblmoon;               // グレゴリオ暦=旧暦テーブル
  18:     var $language;              // 表示言語(jp:日本語, en:英語, en3:英語略記)
  19:     var $resolve2033;           // 旧暦2033年問題解決案 0:解決しない,1:案1,2:案2,3:対応案3  https://www.pahoo.org/e-soul/webtech/php02/php02-45-01.shtm#php_resolveLunarCalendar2033
  20:     var $pcc;                   // pahooCacheインスタンス
  21:     var $CabinetOfficeHolidayTables;    // 内閣府が公開している祝日表
  22:     const CABINETOFFICE_HOLIDAY_FILE = 'https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv';   // 内閣府が公開している祝日表URL
  23: 
  24: /**
  25:  * コンストラクタ
  26:  * @param   string $language 表示言語;省略時 jp
  27:  * @param   float  $tdiff    世界時との時差(省略時 +9.0;日本標準時)
  28:  * @param   object $pcc      pahooCacheインスタンス;省略時 NULL
  29:  *              インターネット経由で内閣府の国民の祝日を参照するときに指定
  30:  * @return  bool オブジェクト/FALSE:$tdiffが不正
  31: */
  32: function __construct($language='jp', $tdiff=+9.0, $pcc=NULL) {
  33:     $this->error  = FALSE;
  34:     $this->errmsg = '';
  35:     $this->year  = date('Y');
  36:     $this->month = date('n');
  37:     $this->day   = date('j');
  38:     $this->resolve2033 = 0;
  39:     $this->pcc = $pcc;
  40:     $this->CabinetOfficeHolidayTables = array();
  41: 
  42:     $this->setLanguage($language);
  43:     if ($this->setTimeDifference($tdiff) == FALSE) {
  44:         $this->error = TRUE;
  45:         $this->errmsg = 'illegal tdiff';
  46:     }
  47: }

西暦(グレゴリオ暦)計算やヒジュラ暦(イスラム暦)への変換、祝祭日、六曜、二十四節気の算出などの暦関係の計算、太陽や月の位置計算、潮位などを求めるクラス・ファイル "pahooCalendar.php" が同梱されているが、include_path が通ったディレクトリに配置してほしい。他のプログラムでも "pahooCalendar.php" を利用するが、常に最新のクラス・ファイルを1つ配置すればよい。

準備:pahooGeoCode クラス

pahooGeoCode.php

  41: class pahooGeoCode {
  42:     public $items;      // 検索結果格納用
  43:     public $error;      // エラー・フラグ
  44:     public $errmsg;     // エラー・メッセージ
  45:     public $hits;       // 検索ヒット件数
  46:     public $webapi; // 直前に呼び出したWebAPI URL
  47: 
  48:     // 都道府県境界線データ
  49:     // SimpleMaps.com is a product of Pareto Software, LLC. © 2010-2025
  50:     // https://simplemaps.com/gis/country/jp
  51:     // ※各自の環境に合わせて設定すること
  52:     public $GeoJsonJP = __DIR__ . '/jp.json';
  53: 
  54:     // -- 以下のデータは .env ファイルに記述可能
  55:     // Google Cloud Platform APIキー
  56:     // https://cloud.google.com/maps-platform/
  57:     // ※Google Maps APIを利用しないのなら登録不要
  58:     public $GOOGLE_API_KEY_1 = '';      // HTTPリファラ用
  59:     public $GOOGLE_API_KEY_2 = '';      // IP制限用
  60:     public $GOOGLE_MAP_ID    = '';      // GoogleMaps ID
  61: 
  62:     // Yahoo! JAPAN Webサービス アプリケーションID
  63:     // https://e.developer.yahoo.co.jp/register
  64:     // ※Yahoo! JAPAN Webサービスを利用しないのなら登録不要
  65:     public $YAHOO_APPLICATION_ID = '';
  66: 
  67:     // OSM Nominatim Search API利用時に知らせるメールアドレス
  68:     // https://wiki.openstreetmap.org/wiki/JA:Nominatim#.E6.A4.9C.E7.B4.A2
  69:     // ※OSM Nominatim Search APIを利用しないのなら登録不要
  70:     public $NOMINATIM_EMAIL = '';
  71: 
  72:     // IP2Location.io APIキー
  73:     // https://www.ip2location.io/
  74:     // ※IP2Location.ioを利用しないのなら登録不要
  75:     public $IP2LOCATION_API_KEY = '';

GoogleマップやLeafletなどによる地図描画や住所検索を行うためのクラスが pahooGeoCode である。同梱のクラス・ファイル "pahooGeoCode.php" は include_path が通ったディレクトリに配置してほしい。他のプログラムでも pahooGeoCodeクラス を利用するが、常に最新のクラス・ファイルを1つ配置すればよい。

地図や住所検索として Google を利用するのであれば Google Cloud Platform APIキーマップID が必要で、その入手方法は「Google Cloud Platform - WebAPIの登録方法」を、Yahoo!JAPAN を利用するのであれば Yahoo! JAPAN Webサービス アプリケーションIDが必要で、その入手方法は「Yahoo!JAPAN デベロッパーネットワーク - WebAPIの登録方法」を、IP2Location.ioを利用するのであれば「PHPでIPアドレスやホスト名から住所を求める」を、それぞれ参照されたい。

PHPのクラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」を参照されたい。

準備:地図サービスの選択

getPrecipitation.php

  51: //地図描画サービスの選択
  52: //    0:Google
  53: //    2:地理院地図・OSM
  54: define('MAPSERVICE', 2);
  55: 
  56: //住所検索サービスの選択
  57: //    0:Google
  58: //    1:Yahoo!JAPAN
  59: //   11:HeartRails Geo API
  60: //   12:OSM Nominatim Search API
  61: //   13:国土地理院ジオコーディングAPI
  62: define('GEOSERVICE', 1);
  63: 
  64: //逆ジオコーディングサービスの選択
  65: //    0:Google
  66: //    1:Yahoo!JAPAN
  67: //   11:HeartRails Geo API
  68: //   21:簡易ジオコーディングサービス
  69: define('REVGEOSERVICE', 1);

表示する地図は、Googleマップ地理院地図・オープンストリートマップ(OSM)から選べる。あらかじめ、定数 MAPSERVIC に値を設定すること。
住所検索サービスは、GoogleYahoo!JAPANHeartRails Geo APIOSM Nominatim Search API国土地理院ジオコーディングAPI から選べる。あらかじめ、定数 GEOSERVICE に値を設定すること。
逆ジオコーディングサービスは、GoogleYahoo!JAPANHeartRails Geo API簡易ジオコーディングサービスから選べる。あらかじめ、定数 REVGEOSERVICE に値を設定すること。
PHPで空き室のあるホテルを検索する
地理院地図(淡色)
PHPで空き室のあるホテルを検索する
OpenStreetMap

準備:pahooRakuten クラス

pahooRakuten.php

  19: // 楽天ウェブサービス・クラス ===============================================
  20: class pahooRakuten {
  21:     public $error;          // エラー・フラグ
  22:     public $errmsg;     // エラー・メッセージ
  23:     public $hits;           // 検索ヒット件数
  24:     public $webapi;     // 直前に呼び出したWebAPI URL
  25: 
  26:     // 楽天ウェブサービス
  27:     // https://www.pahoo.org/e-soul/webtech/php06/php06-01-02.shtm#Rakuten 参照
  28:     public $APPLICATIONID      = '';        // アプリID
  29:     public $APPLICATION_SECRET = '';        // シークレット
  30:     public $AFFILIATEID        = '';        // アフィリエイトID
  31: 
  32: /**
  33:  * コンストラクタ
  34:  * @param   なし
  35:  * @return  なし
  36: */
  37: function __construct() {
  38:     if (isset($_ENV['PAHOO_RAKUTEN_APP_ID'])) {
  39:         $this->APPLICATIONID = $_ENV['PAHOO_RAKUTEN_APP_ID'];
  40:     }
  41:     if (isset($_ENV['PAHOO_RAKUTEN_APP_SECRET'])) {
  42:         $this->APPLICATION_SECRET = $_ENV['PAHOO_RAKUTEN_APP_SECRET'];
  43:     }
  44:     if (isset($_ENV['PAHOO_RAKUTEN_AFFILIATEID'])) {
  45:         $this->AFFILIATEID = $_ENV['PAHOO_RAKUTEN_AFFILIATEID'];
  46:     }
  47: 
  48:     // プロパティを初期化する.
  49:     $this->error  = FALSE;
  50:     $this->errmsg = '';
  51:     $this->hits   = 0;
  52:     $this->webapi = '';
  53: }

楽天トラベルのホテル検索、楽天市場の商品検索など、楽天ウェブサービスを利用するためのクラスファイルが "pahooRakuten.php" である。同梱のクラス・ファイル "pahooRakuten.php" は include_path が通ったディレクトリに配置してほしい。他のプログラムでも pahooGeoCodeクラス を利用するが、常に最新のクラス・ファイルを1つ配置すればよい。

楽天ウェブサービスには、アプリIDアフィリエイトID が必要で、その入手方法は「楽天ウェブサービス - WebAPIの登録方法」を参照されたい。

PHPのクラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」を参照されたい。

「楽天トラベル施設検索API」による施設情報検索

楽天トラベル空室検索API」は、入力パラメータ(IN)は GET 渡しで、出力結果(OUT)は XML で戻るという形である。今回使う入力パラメータと出力結果のデータ構造を以下に示す。
WebAPIのURL
URL
https://app.rakuten.co.jp/services/api/Travel/VacantHotelSearch/20170426

入力パラメータ
フィールド名 要否 内  容
appid 必須 楽天ウェブサービスのアプリケーションID。
affiliateId 任意 楽天ウェブサービスのアフィリエイトID。
format 任意 レスポンス形式:'xml'または'json'
【デフォルト】json
callback 任意 JSONPとして出力する際のコールバック関数名 (UTF-8でURLエンコードした文字列)
英数字、「.(ドット)」、「_(アンダーバー)」、「[(中括弧)」、「](中括弧)」のいずれか1文字以上
elements 任意 出力パラメーター指定:カンマ区切りで、必要な出力パラメータを指定した場合、指定された出力パラメータのみを返却する。
【デフォルト】ALL
latitude 必須 緯度:日本測地系、単位は秒、ミリ秒は小数点以下2桁以内で指定すること。
例)128216.17
ただし、datumTypeに1を指定した場合は、世界測地系、単位は度で指定すること。
例)35.6065914
longitude 必須 経度。日本測地系、単位は秒、ミリ秒は小数点以下2桁以内で指定すること。
例)503259.29
ただし、datumTypeに1を指定した場合は、世界測地系、単位は度で指定すること。
例)139.7513225
searchRadius 任意 検索半径:緯度経度検索時の検索半径(単位km)
0.1以上、3.0以下
小数点以下は1桁までであること
datumType 任意 緯度経度タイプ:入力及び出力パラメータの緯度経度タイプを指定する。
1:世界測地系、単位は度。
2:日本測地系、単位は秒。
【デフォルト】2
2025年(令和7年)8月現在、datumType = 1 を指定したときにデータを取得できない状態であるため、datumType = 2 として、日本測地系を渡すようにデグレードした。
応答データ(xml) root pagingInfo recordCount 検索結果総数 pageCount 総ページ数 page ページ番号 first ページ内結果開始番号 last ページ内結果終了番号 hotels hotel hotelBasicInfo hotelNo 施設番号 hotelName 施設名称 hotelInformationUrl 施設情報ページURL planListUrl 宿泊プラン一覧ページURL dpPlanListUrl ダイナミックパッケージ宿泊プラン一覧ページURL reviewUrl お客様の声ページURL hotelKanaName 施設かな名称 hotelSpecial 施設特色 hotelMinCharge 最安料金 latitude 緯度 longitude 経度 postalCode 郵便番号 address1 住所1 address2 住所2 telephoneNo 施設電話番号 faxNo ファックス番号 access 施設へのアクセス parkingInformation 駐車場情報 nearestStation 最寄駅名称 hotelImageUrl 施設画像URL hotelThumbnailUrl 施設画像サムネイルURL roomImageUrl 部屋画像URL roomThumbnailUrl 部屋画像サムネイルURL hotelMapImageUrl 施設提供地図画像URL reviewCount 投稿件数 reviewAverage ★の数(総合) userReview お客さまの声(1件目)

解説:クラウドサービス呼び出し

pahooRakuten.php

  90: /**
  91:  * WebAPIを呼び出して応答データを取得する(https用)
  92:  * @param   string $url リスクエストURL
  93:  * @return  string 応答データ/FALSE=失敗
  94: */
  95: function callWebAPI($url) {
  96:     $ch = curl_init($url);
  97:     curl_setopt($ch, CURLOPT_HEADER, FALSE);
  98:     curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  99:     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // サーバ証明書検証をスキップ
 100:     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //  〃
 101:     $result = curl_exec($ch);
 102:     if (PHP_VERSION_ID < 80500) {
 103:         curl_close($ch);
 104:     }
 105: 
 106:     return $result;
 107: }

WebAPIはhttpsプロトコルであるため、ユーザー関数 callWebAPI のように cURL 関数を用いて呼び出している。このあたりについては「PHPセキュリティ対策:SSL通信を行う」で解説している。

解説:日付選択

チェックイン日・チェックアウト日を指定するのに、jQuery UIの Datepicker を利用した。カレンダーから年月日を選択できる。
祝祭日の設定については、「PHPで日付入力:カレンダーから選択」をご覧いただきたい。

search_vacant_hotel.php

 108: $HtmlHeader =<<< EOT
 109: <!DOCTYPE html>
 110: <html lang="ja">
 111: <head>
 112: <meta charset="{$encode}">
 113: <title>{$title}</title>
 114: <meta name="author" content="studio pahoo" />
 115: <meta name="copyright" content="studio pahoo" />
 116: <meta name="ROBOTS" content="NOINDEX,NOFOLLOW" />
 117: <meta http-equiv="pragma" content="no-cache">
 118: <meta http-equiv="cache-control" content="no-cache">
 119: <meta http-equiv="X-UA-Compatible" content="IE=edge">
 120: <meta name="viewport" content="width={$width},user-scalable=yes">
 121: <link type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/ui-lightness/jquery-ui.css" rel="stylesheet" />
 122: <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

search_vacant_hotel.php

 362: <td>チェックイン日</td><td><input type="text" class="datepicker" name="checkin" id="checkin" size="12" value="{$spot['checkin']}" /></td>
 363: <td>チェックアウト日</td><td><input type="text" class="datepicker" name="checkout" id="checkout" size="12" value="{$spot['checkout']}" /></td>

解説:ホテル検索

pahooRakuten.php

 111: var $RakutenBooksItems = array(
 112:     'title',            // 書籍タイトル
 113:     'titleKana',        // 書籍タイトル カナ
 114:     'subTitle',         // 書籍サブタイトル
 115:     'subTitleKana',     // 書籍サブタイトル カナ
 116:     'seriesName',       // 叢書名
 117:     'seriesNameKana',   // 叢書名カナ
 118:     'contents',         // 多巻物収録内容
 119:     'contentsKana',     // 多巻物収録内容カナ
 120:     'author',           // 著者名
 121:     'authorKana',       // 著者名カナ
 122:     'publisherName',    // 出版社名
 123:     'size',             // 書籍のサイズ
 124:     'isbn',             // ISBNコード(書籍コード)
 125:     'itemCaption',      // 商品説明文
 126:     'salesDate',        // 発売日
 127:     'itemPrice',        // 税込み販売価格
 128:     'listPrice',        // 定価
 129:     'discountRate',     // 割引率
 130:     'discountPrice',    // 割引価格
 131:     'itemUrl',          // 商品URL
 132:     'affiliateUrl',     // アフィリエイトURL
 133:     'smallImageUrl',    // 商品画像 64x64URL
 134:     'mediumImageUrl',   // 商品画像 128x128URL
 135:     'largeImageUrl',    // 商品画像 200x200URL
 136:     'chirayomiUrl',     // チラよみURL
 137:     'availability',     // 在庫状況
 138:     'postageFlag',      // 送料フラグ
 139:     'limitedFlag',      // 限定フラグ
 140:     'reviewCount',      // レビュー件数
 141:     'reviewAverage',    // レビュー平均
 142:     'booksGenreId'      // 楽天ブックスジャンルID
 143: );

pahooRakuten.php

 462: /**
 463:  * 楽天トラベル空室検索API のURLを取得する
 464:  * ※datumType=1 が効かなくなった?
 465:  * @param   float  $latitude  緯度(世界測地系)
 466:  * @param   float  $longitude 経度(世界測地系)
 467:  * @param   int    $searchRadius 検索半径,単位km
 468:  * @param   string $checkin  チェックイン年月日(YYYY-MM-DD)
 469:  * @param   string $checkout チェックアウト年月日(YYYY-MM-DD)
 470:  * @return  string URL 楽天トラベル空室検索API のURL
 471: */
 472: function searchVacantHotelsURL($latitude, $longitude, $searchRadius, $checkin, $checkout) {
 473:     $appid = $this->APPLICATIONID;
 474:     $affid = $this->AFFILIATEID;
 475: 
 476:     // datumType=1 が機能しないため日本測地系にデグレード(2025/08/14)
 477:     // 世界測地系→日本測地系 変換
 478:     $glng = $longitude + $latitude * 0.000046047 + $longitude * 0.000083049 - 0.010041;
 479:     $glat = $latitude  + $latitude * 0.00010696  - $longitude * 0.000017467 - 0.0046020;
 480:     // 度分秒→秒 変換
 481:     $lat = round($glat * 3600, 2);
 482:     $lng = round($glng * 3600, 2);
 483: 
 484:     $url = "https://app.rakuten.co.jp/services/api/Travel/VacantHotelSearch/20170426?datumType=2&applicationId={$appid}&affiliateId={$affid}&format=xml&latitude={$lat}&longitude={$lng}&searchRadius={$searchRadius}&checkinDate={$checkin}&checkoutDate={$checkout}&responseType=large&searchPattern=0";
 485: 
 486:     return $url;
 487: }

pahooRakuten.php

 489: /**
 490:  * 楽天トラベル系API を利用してホテルを検索する
 491:  * @param   array  $items 情報を格納する配列
 492:  * @param   float  $latitude  緯度(世界測地系)
 493:  * @param   float  $longitude 経度(世界測地系)
 494:  * @param   int    $searchRadius 検索半径,単位km
 495:  * @param   array  $squeezeConditions 絞込み条件の配列:省略可能
 496:  * @param   string $checkin  チェックイン年月日(YYYY-MM-DD):省略可能
 497:  * @param   string $checkout チェックアウト年月日(YYYY-MM-DD):省略可能
 498:  * @return  ヒットした件数/FALSE:検索に失敗
 499: */
 500: function searchHotels(&$items, $latitude, $longitude, $searchRadius, $squeezeConditions=array(''), $checkin='', $checkout='') {
 501:     // 楽天トラベル空室検索API
 502:     if (preg_match('/\d{4}\-\d{2}\-\d{2}/i', $checkin> 0) {
 503:         $url = $this->searchVacanthotelsURL($latitude, $longitude, $searchRadius, $checkin, $checkout);
 504:     // 楽天トラベル施設検索API
 505:     } else {
 506:         $url = $this->searchHotelsURL($latitude, $longitude, $searchRadius, $squeezeConditions);
 507:     }
 508: 
 509:     // APIコール
 510:     if (($res = $this->callWebAPI($url)) == FALSE) {
 511:         $this->error  = TRUE;
 512:         $this->errmsg = 'WebAPI呼び出しに失敗';
 513:         return FALSE;
 514:     }
 515:     $this->webapi = $url;
 516: 
 517: // PHP4用DOM XML利用
 518:     if ($this->isphp5over() == FALSE) {
 519:         if (($dom = domxml_open_mem($res)) == NULL) {
 520:             $this->error  = TRUE;
 521:             $this->errmsg = '楽天トラベルAPIの不具合';
 522:             $this->hits = 0;
 523:             return FALSE;
 524:         }
 525:         $pagingInfo = $dom->get_elements_by_tagname('pagingInfo');
 526:         // レスポンス・チェック
 527:         if (! is_object($pagingInfo )) {
 528:             $this->error  = TRUE;
 529:             $this->errmsg = 'ホテルが見当たらない';
 530:             $this->hits = 0;
 531:             return FALSE;
 532:         }
 533:         $rc = $pagingInfo[0]->get_elements_by_tagname('recordCount');
 534:         if (! is_object($rc)) {
 535:             $this->error  = TRUE;
 536:             $this->errmsg = 'ホテルが見当たらない';
 537:             $this->hits = 0;
 538:             return FALSE;
 539:         }
 540:         $rc = (int)$rc[0]->get_content();
 541:         if ($rc <0) {
 542:             $this->error  = TRUE;
 543:             $this->errmsg = 'ホテルが見当たらない';
 544:             $this->hits = 0;
 545:             return FALSE;
 546:         }
 547:         // 検索結果取りだし
 548:         $hotels = $dom->get_elements_by_tagname('hotels');
 549:         $hotel  = $hotels[0]->get_elements_by_tagname('hotel');
 550:         $cnt = 1;
 551:         foreach ($hotel as $val) {
 552:             foreach ($this->RakutenHotelItems as $name) {
 553:                 $node = $val->get_elements_by_tagname('hotelBasicInfo');
 554:                 $node = $node[0]->get_elements_by_tagname($name);
 555:                 if ($node !NULL) {
 556:                     $items[$cnt][$name] = (string)$node[0]->get_content();
 557:                 }
 558:             }
 559:             $items[$cnt]['id']          = $this->num2alpha($cnt);
 560:             $items[$cnt]['title']       = $items[$cnt]['hotelName'];
 561:             $items[$cnt]['description'] =<<< EOT
 562: <a href="{$items[$cnt]['hotelInformationUrl']}" target="_blank">{$items[$cnt]['hotelName']}</a>&nbsp;({$items[$cnt]['address1']}{$items[$cnt]['address2']})
 563: EOT;
 564:             $cnt++;
 565:         }
 566: 
 567: // PHP5用SimpleXML利用
 568:     } else {
 569:         $xml = simplexml_load_string($res);
 570:         if ($xml == '' || $xml == FALSE) {
 571:             $this->error  = TRUE;
 572:             $this->errmsg = '楽天トラベルAPIの不具合';
 573:             $this->hits = 0;
 574:             return FALSE;
 575:         }
 576:         // レスポンス・チェック
 577:         if ($xml->pagingInfo->recordCount <0) {
 578:             $this->error  = TRUE;
 579:             $this->errmsg = 'ホテルが見当たらない';
 580:             $this->hits = 0;
 581:             return FALSE;
 582:         }
 583:         // 検索結果取りだし
 584:         $cnt = 1;
 585:         $hotel = $xml->hotels->hotel;
 586:         foreach ($hotel as $element) {
 587:             foreach ($this->RakutenHotelItems as $name) {
 588:                 if (isset($element->hotelBasicInfo->$name)) {
 589:                     $items[$cnt][$name] = (string)$element->hotelBasicInfo->$name;
 590:                 } else if (isset($element->hotelDetailInfo->$name)) {
 591:                     $items[$cnt][$name] = (string)$element->hotelDetailInfo->$name;
 592:                 }
 593:             }
 594:             // 部屋設備情報取り出し
 595:             if (isset($element->hotelFacilitiesInfo->roomFacilities->item)) {
 596:                 $node = $element->hotelFacilitiesInfo->roomFacilities->item;
 597:                 $i = 0;
 598:                 while (isset($node[$i])) {
 599:                     $items[$cnt]['roomFacilities'][$i] = (string)$node[$i];
 600:                     $i++;
 601:                 }
 602:             }
 603:             // Googleマップ描画用
 604:             $items[$cnt]['id']          = $this->num2alpha($cnt);
 605:             $items[$cnt]['title']       = $items[$cnt]['hotelName'];
 606:             $items[$cnt]['description'] =<<< EOT
 607: <a href="{$items[$cnt]['hotelInformationUrl']}" target="_blank">{$items[$cnt]['hotelName']}</a>&nbsp;({$items[$cnt]['address1']}{$items[$cnt]['address2']})
 608: EOT;
 609:             $cnt++;
 610:         }
 611:     }
 612:     $this->hits = $cnt - 1;
 613: 
 614:     return $this->hits;
 615: }

応答データの要素が多いので、取得したい要素を $RakutenHotelItems にあらかじめ定義しておき、ユーザー関数 searchHotels の中で付き合わせながら配列$items に格納していく。

ユーザー関数 searchHotels の引数 $checkin$checkout は省略可能で、省略した場合は、今回使用している「楽天トラベル空室検索API」を呼び出す。省略しなければ、「楽天トラベル施設検索API」を呼び出す。

参考サイト

(この項おわり)
header