サンプル・プログラムの実行例
サンプル・プログラム
search_hotel.php | サンプル・プログラム本体。 |
pahooGeoCode.php | 住所・緯度・経度に関わるクラス pahooGeoCode。 使い方は「PHPで住所・ランドマークから最寄り駅を求める」「PHPで住所・ランドマークから緯度・経度を求める」などを参照。include_path が通ったディレクトリに配置すること。 |
pahooRakuten.php | 楽天ウェブサービスに関わるクラス pahooRakuten。 使い方は「PHPで最寄りのネットができるホテルを検索する」などを参照。include_path が通ったディレクトリに配置すること。 |
pahooInputData.php | データ入力に関わる関数群。 使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
バージョン | 更新日 | 内容 |
---|---|---|
5.5.0 | 2023/07/14 | 検索キーの最小・最大長の指定 |
5.4.0 | 2023/07/02 | 国土地理院ジオコーディングAPIを追加 |
5.31 | 2022/03/20 | マップ移動時に緯度・経度を拾わない不具合を修正 |
5.3 | 2021/02/20 | PHP8対応,Yahoo! JavaScriptマップ廃止 |
5.2 | 2020/03/21 | OSM Nominatim Search API追加 |
バージョン | 更新日 | 内容 |
---|---|---|
6.3.3 | 2024/09/14 | $this->NOMINATIM_EMAIL 追加 |
6.3.2 | 2024/02/14 | getStaticMap() -- bug-fix |
6.3.1 | 2023/07/09 | bug-fix |
6.3.0 | 2023/07/02 | getPointsGSI()追加 |
6.2.0 | 2023/07/02 | ip2address()追加 |
バージョン | 更新日 | 内容 |
---|---|---|
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)に変更 |
3.5 | 2021/10/24 | PHP8対応 |
3.4 | 2020/05/24 | 楽天書籍API (version:2017-04-04)に変更 |
バージョン | 更新日 | 内容 |
---|---|---|
1.5.0 | 2024/01/28 | exitIfExceedVersion() 追加 |
1.4.2 | 2024/01/28 | exitIfLessVersion() メッセージ修正 |
1.4.1 | 2023/09/30 | コメントの訂正 |
1.4.0 | 2023/09/09 | $_GET, $_POST参照をfilter_input()関数に置換 |
1.3.0 | 2023/07/11 | roundFloat() 追加 |
サンプル・プログラムの流れ
準備:pahooGeoCode クラス
37: class pahooGeoCode {
38: var $items; //検索結果格納用
39: var $error; //エラー・フラグ
40: var $errmsg; //エラー・メッセージ
41: var $hits; //検索ヒット件数
42: var $webapi; //直前に呼び出したWebAPI URL
43:
44: //Google Cloud Platform APIキー
45: //https://cloud.google.com/maps-platform/
46: //※Google Maps APIを利用しないのなら登録不要
47: var $GOOGLE_API_KEY_1 = '**************************'; //HTTPリファラ用
48: var $GOOGLE_API_KEY_2 = '**************************'; //IP制限用
49:
50: //Yahoo! JAPAN Webサービス アプリケーションID
51: //https://e.developer.yahoo.co.jp/register
52: //※Yahoo! JAPAN Webサービスを利用しないのなら登録不要
53: var $YAHOO_APPLICATION_ID = '*****************************';
クラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」を参照されたい。
地図や住所検索として Google を利用するのであれば、Google Cloud Platform APIキー が必要で、その入手方法は「Google Cloud Platform - WebAPIの登録方法」を、Yahoo!JAPAN を利用するのであれば、Yahoo! JAPAN Webサービス アプリケーションIDが必要で、その入手方法は「Yahoo!JAPAN デベロッパーネットワーク - WebAPIの登録方法」を、それぞれ参照されたい。
準備:地図サービス(クラウドサービス)の選択
57: //地図描画サービスの選択
58: // 0:Google
59: // 2:地理院地図・OSM
60: define('MAPSERVICE', 2);
61:
62: //住所検索サービスの選択
63: // 0:Google
64: // 1:Yahoo!ジオコーダAPI
65: // 11:HeartRails Geo API
66: // 12:OSM Nominatim Search API
67: // 13:国土地理院ジオコーディングAPI
68: define('GEOSERVICE', 1);
69:
70: //逆ジオコーディングサービスの選択
71: // 0:Google
72: // 1:Yahoo!JAPAN
73: // 11:HeartRails Geo API
74: // 21:簡易ジオコーディングサービス
75: define('REVGEOSERVICE', 1);
住所検索サービスは、Google、HeartRails Geo API、OSM Nominatim Search API から選べる。あらかじめ、定数 GEOSERVICE に値を設定すること。
逆ジオコーディングサービスは、Google、Yahoo!JAPAN、HeartRails Geo API、簡易ジオコーディングサービスから選べる。あらかじめ、定数 REVGEOSERVICE に値を設定すること。
準備:pahooRakuten クラス
16: // 楽天ウェブサービス・クラス ===============================================
17: class pahooRakuten {
18: var $error; //エラー・フラグ
19: var $errmsg; //エラー・メッセージ
20: var $hits; //検索ヒット件数
21: var $webapi; //直前に呼び出したWebAPI URL
22:
23: //楽天ウェブサービス
24: //https://www.pahoo.org/e-soul/webtech/php06/php06-01-02.shtm#Rakuten 参照
25: var $APPLICATIONID = '*******************'; //アプリID
26: var $APPLICATION_SECRET = '****************'; //シークレット
27: var $AFFILIATEID = '*******************'; //アフィリエイトID
クラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」を参照されたい。
楽天ウェブサービスには、アプリID や アフィリエイトID が必要で、その入手方法は「楽天ウェブサービス - WebAPIの登録方法」を参照されたい。
「楽天トラベル施設検索API」による施設情報検索
URL |
---|
https://app.rakuten.co.jp/services/api/Travel/SimpleHotelSearch/20170426 |
フィールド名 | 要否 | 内 容 |
---|---|---|
appid | 必須 | 楽天ウェブサービスのアプリケーション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 |
squeezeCondition | 任意 | kinen:禁煙ルーム internet:インターネットが出来る部屋 daiyoku:大浴場あり onsen:温泉 |
解説:クラウドサービスの呼び出し
76: /**
77: * WebAPIを呼び出して応答データを取得する(https用)
78: * @param string $url リスクエストURL
79: * @return string 応答データ/FALSE=失敗
80: */
81: function callWebAPI($url) {
82: $ch = curl_init($url);
83: curl_setopt($ch, CURLOPT_HEADER, FALSE);
84: curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
85: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); //サーバ証明書検証をスキップ
86: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 〃
87: $result = curl_exec($ch);
88: curl_close($ch);
89:
90: return $result;
91: }
解説:ホテル検索
95: var $RakutenBooksItems = array(
96: 'title', //書籍タイトル
97: 'titleKana', //書籍タイトル カナ
98: 'subTitle', //書籍サブタイトル
99: 'subTitleKana', //書籍サブタイトル カナ
100: 'seriesName', //叢書名
101: 'seriesNameKana', //叢書名カナ
102: 'contents', //多巻物収録内容
103: 'contentsKana', //多巻物収録内容カナ
104: 'author', //著者名
105: 'authorKana', //著者名カナ
106: 'publisherName', //出版社名
107: 'size', //書籍のサイズ
108: 'isbn', //ISBNコード(書籍コード)
109: 'itemCaption', //商品説明文
110: 'salesDate', //発売日
111: 'itemPrice', //税込み販売価格
112: 'listPrice', //定価
113: 'discountRate', //割引率
114: 'discountPrice', //割引価格
115: 'itemUrl', //商品URL
116: 'affiliateUrl', //アフィリエイトURL
117: 'smallImageUrl', //商品画像 64x64URL
118: 'mediumImageUrl', //商品画像 128x128URL
119: 'largeImageUrl', //商品画像 200x200URL
120: 'chirayomiUrl', //チラよみURL
121: 'availability', //在庫状況
122: 'postageFlag', //送料フラグ
123: 'limitedFlag', //限定フラグ
124: 'reviewCount', //レビュー件数
125: 'reviewAverage', //レビュー平均
126: 'booksGenreId' //楽天ブックスジャンルID
127: );
420: /**
421: * 楽天トラベル施設検索API のURLを取得する
422: * @param double $latitude 緯度(世界測地系)
423: * @param double $longitude 経度(世界測地系)
424: * @param int $searchRadius 検索半径,単位km
425: * @param array $squeezeConditions 絞込み条件の配列
426: * @return string URL 楽天トラベル施設検索API のURL
427: */
428: function searchHotelsURL($latitude, $longitude, $searchRadius, $squeezeConditions) {
429: $appid = $this->APPLICATIONID;
430: $affid = $this->AFFILIATEID;
431: $res = "https://app.rakuten.co.jp/services/api/Travel/SimpleHotelSearch/20170426?applicationId={$appid}&affiliateId={$affid}&format=xml&latitude={$latitude}&longitude={$longitude}&searchRadius={$searchRadius}&datumType=1&responseType=large";
432:
433: //絞り込み条件
434: foreach ($squeezeConditions as $key=>$val) {
435: if ($key == 0) {
436: $res .= "&squeezeCondition={$val}";
437: } else {
438: $res .= ",{$val}";
439: }
440: }
441:
442: return $res;
443: }
462: /**
463: * 楽天トラベル系API を利用してホテルを検索する
464: * @param array $items 情報を格納する配列
465: * @param double $latitude 緯度(世界測地系)
466: * @param double $longitude 経度(世界測地系)
467: * @param int $searchRadius 検索半径,単位km
468: * @param array $squeezeConditions 絞込み条件の配列:省略可能
469: * @param string $checkin チェックイン年月日(YYYY-MM-DD):省略可能
470: * @param string $checkout チェックアウト年月日(YYYY-MM-DD):省略可能
471: * @return ヒットした件数/FALSE:検索に失敗
472: */
473: function searchHotels(&$items, $latitude, $longitude, $searchRadius, $squeezeConditions=array(''), $checkin='', $checkout='') {
474: //楽天トラベル空室検索API
475: if (preg_match('/\d{4}\-\d{2}\-\d{2}/i', $checkin) > 0) {
476: $url = $this->searchVacanthotelsURL($latitude, $longitude, $searchRadius, $checkin, $checkout);
477: //楽天トラベル施設検索API
478: } else {
479: $url = $this->searchHotelsURL($latitude, $longitude, $searchRadius, $squeezeConditions);
480: }
481:
482: //APIコール
483: if (($res = $this->callWebAPI($url)) == FALSE) {
484: $this->error = TRUE;
485: $this->errmsg = 'WebAPI呼び出しに失敗';
486: return FALSE;
487: }
488: $this->webapi = $url;
489:
490: //PHP4用; DOM XML利用
491: if ($this->isphp5over() == FALSE) {
492: if (($dom = domxml_open_mem($res)) == NULL) {
493: $this->error = TRUE;
494: $this->errmsg = '楽天トラベルAPIの不具合';
495: $this->hits = 0;
496: return FALSE;
497: }
498: $pagingInfo = $dom->get_elements_by_tagname('pagingInfo');
499: //レスポンス・チェック
500: if (! is_object($pagingInfo )) {
501: $this->error = TRUE;
502: $this->errmsg = 'ホテルが見当たらない';
503: $this->hits = 0;
504: return FALSE;
505: }
506: $rc = $pagingInfo[0]->get_elements_by_tagname('recordCount');
507: if (! is_object($rc)) {
508: $this->error = TRUE;
509: $this->errmsg = 'ホテルが見当たらない';
510: $this->hits = 0;
511: return FALSE;
512: }
513: $rc = (int)$rc[0]->get_content();
514: if ($rc <= 0) {
515: $this->error = TRUE;
516: $this->errmsg = 'ホテルが見当たらない';
517: $this->hits = 0;
518: return FALSE;
519: }
520: //検索結果取りだし
521: $hotels = $dom->get_elements_by_tagname('hotels');
522: $hotel = $hotels[0]->get_elements_by_tagname('hotel');
523: $cnt = 1;
524: foreach ($hotel as $val) {
525: foreach ($this->RakutenHotelItems as $name) {
526: $node = $val->get_elements_by_tagname('hotelBasicInfo');
527: $node = $node[0]->get_elements_by_tagname($name);
528: if ($node != NULL) {
529: $items[$cnt][$name] = (string)$node[0]->get_content();
530: }
531: }
532: $items[$cnt]['id'] = $this->num2alpha($cnt);
533: $items[$cnt]['title'] = $items[$cnt]['hotelName'];
534: $items[$cnt]['description'] =<<< EOT
535: <a href="{$items[$cnt]['hotelInformationUrl']}" target="_blank">{$items[$cnt]['hotelName']}</a> ({$items[$cnt]['address1']}{$items[$cnt]['address2']})
536: EOT;
537: $cnt++;
538: }
539:
540: //PHP5用; SimpleXML利用
541: } else {
542: $xml = simplexml_load_string($res);
543: if ($xml == '' || $xml == FALSE) {
544: $this->error = TRUE;
545: $this->errmsg = '楽天トラベルAPIの不具合';
546: $this->hits = 0;
547: return FALSE;
548: }
549: //レスポンス・チェック
550: if ($xml->pagingInfo->recordCount <= 0) {
551: $this->error = TRUE;
552: $this->errmsg = 'ホテルが見当たらない';
553: $this->hits = 0;
554: return FALSE;
555: }
556: //検索結果取りだし
557: $cnt = 1;
558: $hotel = $xml->hotels->hotel;
559: foreach ($hotel as $element) {
560: foreach ($this->RakutenHotelItems as $name) {
561: if (isset($element->hotelBasicInfo->$name)) {
562: $items[$cnt][$name] = (string)$element->hotelBasicInfo->$name;
563: } else if (isset($element->hotelDetailInfo->$name)) {
564: $items[$cnt][$name] = (string)$element->hotelDetailInfo->$name;
565: }
566: }
567: //部屋設備情報取り出し
568: if (isset($element->hotelFacilitiesInfo->roomFacilities->item)) {
569: $node = $element->hotelFacilitiesInfo->roomFacilities->item;
570: $i = 0;
571: while (isset($node[$i])) {
572: $items[$cnt]['roomFacilities'][$i] = (string)$node[$i];
573: $i++;
574: }
575: }
576: //Googleマップ描画用
577: $items[$cnt]['id'] = $this->num2alpha($cnt);
578: $items[$cnt]['title'] = $items[$cnt]['hotelName'];
579: $items[$cnt]['description'] =<<< EOT
580: <a href="{$items[$cnt]['hotelInformationUrl']}" target="_blank">{$items[$cnt]['hotelName']}</a> ({$items[$cnt]['address1']}{$items[$cnt]['address2']})
581: EOT;
582: $cnt++;
583: }
584: }
585: $this->hits = $cnt - 1;
586:
587: return $this->hits;
588: }
旧APIの廃止について
- 楽天トラベル施設検索API
- Version(2009-10-20)
- Version(2009-09-09)
- Version(2008-11-13)
- Version(2007-11-21)
- 楽天トラベル施設情報API
- Version(2009-09-09)
- Version(2009-03-26)
- Version(2008-11-13)
- Version(2007-11-21)
- Version(2007-04-11)
- 楽天トラベル空室検索API
- Version (2009-10-20)
- 楽天トラベル地区コードAPI
- Version (2009-03-26)
- 楽天トラベルキーワード検索API
- Version(2009-10-20)
- Version(2009-09-09)
- 楽天トラベルホテルチェーンAPI
- Version(2009-05-12)
- 楽天トラベルランキングAPI
- Version(2009-06-25)
参考サイト
- 楽天トラベル施設検索API
- PHPで最寄り駅を求める:ぱふぅ家のホームページ
- PHPセキュリティ対策:SSL通信を行う:ぱふぅ家ホームページ
なお、Yahoo! JavaScriptマップは、2020年(令和2年)10月31日をもってサービスを終了しており利用できない。
(2023年7月14日)検索キーの最小・最大長が指定できるようにした.
(2023年7月2日)国土地理院ジオコーディングAPIを利用できるようにした.