PHPでホットペッパーを利用して喫茶店を検索する

(1/1)
ホットペッパーの「グルメサーチAPI」は、指定した緯度・経度の近くにある飲食店を検索できる無料WebAPIサービスだ。ぐるなびAPIの無料サービスが終了してしまったため、代わりにこのサービスを見つけた。地図サービスをクラウド連携することで、住所やランドマークから周辺にある喫茶店を探すPHPプログラムを作ってみる。

(2025年8月13日).pahooEnv導入
(2025年6月14日)GoogleMaps JavaScript APIの変更に対応した.

目次

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

PHPでホットペッパーを利用して喫茶店を検索する
Googleマップ表示
「住所」に、住所やランドマーク、緯度経度を入力して「検索」ボタンをクリックすると、近くにある喫茶店がマップ上に表示されるとともに、一覧表示される。

サンプル・プログラム

圧縮ファイルの内容
searchCafeHotpepper.phpサンプル・プログラム本体
.pahooEnvクラウドサービスを利用するためのアカウント情報などを記入する .env ファイル。
使い方は「各種クラウド連携サービス(WebAPI)の登録方法」を参照。include_path が通ったディレクトリに配置すること。
pahooInputData.phpデータ入力に関わる関数群。
使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。
pahooGeoCode.php住所・緯度・経度に関わるクラス pahooGeoCode。
使い方は「PHPで住所・ランドマークから最寄り駅を求める」などを参照。include_path が通ったディレクトリに配置すること。
searchCafeHotpepper.php 更新履歴
バージョン 更新日 内容
1.1.0 2025/08/13 .pahooEnv導入
1.0 2022/01/10 初版
pahooGeoCode.php 更新履歴
バージョン 更新日 内容
6.8.0 2025/08/10 アクセスキーなどを ".env" に分離
6.7.1 2025/07/26 jsLine_Gmap() - bug-fix
6.7.0 2025/07/20 drawJSmap,drawGMap -- 引数 $markerLevel 追加
6.6.0 2025/07/19 drawJSmap,drawGMap,drawLeaflet -- マップ中心マーカー表示引数を追加
6.5.0 2025/06/14 GoogleMaps JavaScript APIの変更に対応
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() 追加

準備: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)の登録方法」をご覧いただきたい。

準備:pahooGeoCode クラス

pahooGeoCode.php

  40: class pahooGeoCode {
  41:     public $items;      // 検索結果格納用
  42:     public $error;      // エラー・フラグ
  43:     public $errmsg;     // エラー・メッセージ
  44:     public $hits;       // 検索ヒット件数
  45:     public $webapi// 直前に呼び出したWebAPI URL
  46: 
  47:     // -- 以下のデータは .env ファイルに記述可能
  48:     // Google Cloud Platform APIキー
  49:     // https://cloud.google.com/maps-platform/
  50:     // ※Google Maps APIを利用しないのなら登録不要
  51:     public $GOOGLE_API_KEY_1 = '';      // HTTPリファラ用
  52:     public $GOOGLE_API_KEY_2 = '';      // IP制限用
  53:     public $GOOGLE_MAP_ID    = '';      // GoogleMaps ID
  54: 
  55:     // Yahoo! JAPAN Webサービス アプリケーションID
  56:     // https://e.developer.yahoo.co.jp/register
  57:     // ※Yahoo! JAPAN Webサービスを利用しないのなら登録不要
  58:     public $YAHOO_APPLICATION_ID = '';
  59: 
  60:     // OSM Nominatim Search API利用時に知らせるメールアドレス
  61:     // https://wiki.openstreetmap.org/wiki/JA:Nominatim#.E6.A4.9C.E7.B4.A2
  62:     // ※OSM Nominatim Search APIを利用しないのなら登録不要
  63:     public $NOMINATIM_EMAIL = '';
  64: 
  65:     // IP2Location.io APIキー
  66:     // https://www.ip2location.io/
  67:     // ※IP2Location.ioを利用しないのなら登録不要
  68:     public $IP2LOCATION_API_KEY = '';

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

地図や住所検索として 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でクラスを使ってテキストの読みやすさを調べる」を参照されたい。

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

searchCafeHotpepper.php

  64: // 地図描画サービスの選択
  65: //    0:Google
  66: //    2:地理院地図・OSM
  67: define('MAPSERVICE', 0);
  68: 
  69: // 住所検索サービスの選択
  70: //    0:Google
  71: //    1:Yahoo!JAPAN
  72: //   11:HeartRails Geo API
  73: //   12:OSM Nominatim Search API
  74: define('GEOSERVICE', 1);
  75: 
  76: // 逆ジオコーディングサービスの選択
  77: //    0:Google
  78: //    1:Yahoo!JAPAN
  79: //   11:HeartRails Geo API
  80: //   21:簡易ジオコーディングサービス
  81: define('REVGEOSERVICE', 21);

表示する地図は、Googleマップ地理院地図・オープンストリートマップ(OSM)から選べる。あらかじめ、定数 MAPSERVIC に値を設定すること。
住所検索サービスは、GoogleYahoo!JAPANHeartRails Geo APIOSM Nominatim Search API から選べる。あらかじめ、定数 GEOSERVICE に値を設定すること。
逆ジオコーディングサービスは、GoogleYahoo!JAPANHeartRails Geo API簡易ジオコーディングサービスから選べる。あらかじめ、定数 REVGEOSERVICE に値を設定すること。
PHPでホットペッパーを利用して喫茶店を検索する
Open Streetマップ表示

ホットペッパー グルメサーチAPI

ホットペッパー グルメサーチAPIは、入力パラメータ(IN)として GET方式を、出力結果(OUT)がXMLまたはJSONで戻るというAPIである。
WebAPIのURL
URL
https://webservice.recruit.co.jp/hotpepper/gourmet/v1/

入力パラメータ
フィールド名 要否 内  容
key 必須 APIキー
lat 必須 緯度
lng 必須 経度
range 必須 検索範囲
1: 300m
2: 500m
3: 1000m (初期値)
4: 2000m
5: 3000m
datum 任意 world: 世界測地系、tokyo: 旧日本測地系。初期値は world。
genre 任意 お店ジャンルコード。本プログラムでは定数HOTPEPPER_GENREで指定。
count 任意 検索結果の最大出力データ数を指定します。初期値:10、宰相:1、最大100。
format 任意 レスポンス形式。初期値:xml。xml または json または jsonp。
応答データ構造(json) results shop id お店ID name 掲載店名 address 住所 lat 緯度(世界測地系) lng 経度(世界測地系) open 営業時間 close 定休日 genre catch お店ジャンルキャッチ urls pc PC向けURL photo pc l PC用店舗トップ写真(大)画像URL m PC用店舗トップ写真(中)画像URL s PC用店舗トップ写真(小)画像URL wifi Wi-Fi有無 shop id お店ID name 掲載店名 address 住所 lat 緯度(世界測地系) lng 経度(世界測地系) open 営業時間 close 定休日 genre catch お店ジャンルキャッチ urls pc PC向けURL photo pc l PC用店舗トップ写真(大)画像URL m PC用店舗トップ写真(中)画像URL s PC用店舗トップ写真(小)画像URL wifi Wi-Fi有無

解説:喫茶店を検索

searchCafeHotpepper.php

 194: /**
 195:  * グルメサーチAPIのURLを取得する
 196:  * @param   double $latitude  緯度(世界測地系)
 197:  * @param   double $longitude 経度(世界測地系)
 198:  * @param   double $distance  範囲(メートル)
 199:  * @param   string $genre     ジャンルID
 200:  * @return  string URL グルメサーチAPIのURL
 201: */
 202: function getURL_GourmetSearchAPI($latitude, $longitude, $distance, $genre) {
 203:     $range_tbl = array(1=>300, 2=>500, 3=>1000, 4=>2000, 5=>3000);
 204: 
 205:     $apikey = HOTPEPPER_ACCESSKEY;
 206:     $counts = HOTPEPPER_COUNTS;
 207:     $range = count($range_tbl);
 208:     foreach ($range_tbl as $key=>$val) {
 209:         if ($distance <$val) {
 210:             $range = $key;
 211:             break;
 212:         }
 213:     }
 214: 
 215:     $url = "http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key={$apikey}&&lat={$latitude}&lng={$longitude}&range={$range}&genre={$genre}&datum=world&count={$counts}&format=json";
 216: 
 217:     return $url;
 218: }

searchCafeHotpepper.php

 220: /**
 221:  * グルメサーチAPIを利用して指定座標の近くにある喫茶店を検索
 222:  * @param   double $latitude  緯度(世界測地系)
 223:  * @param   double $longitude 経度(世界測地系)
 224:  * @param   double $distance  範囲(メートル)
 225:  * @param   array $items 情報を格納する配列
 226:  * @return  array(ヒットした施設数, メッセージ, APIのURL)
 227: */
 228: function searchCafe($latitude, $longitude, $distance, &$items) {
 229:     $msg = '';
 230:     $url = getURL_GourmetSearchAPI($latitude, $longitude, $distance, HOTPEPPER_GENRE);
 231:     $data = @file_get_contents($url);
 232:     $json = json_decode($data);
 233: 
 234:     // レスポンス・チェック
 235:     if (($data == FALSE|| ($json == NULL)) {
 236:         if (isset($json->results->results_available&& ((int)($json->results->results_available<0)) {
 237:             $msg = '検索範囲に店舗が無いか,ホットペッパーAPIのエラーです';
 238:         }
 239:         return array(FALSE, $msg, $url);
 240:     }
 241: 
 242:     // 応答解釈
 243:     $n = 1;
 244:     foreach ($json->results->shop as $element) {
 245:         $items[$n]['id']        = num2alpha($n);
 246:         $items[$n]['title']     = (string)$element->name;
 247:         $items[$n]['url']       = (string)$element->urls->pc;
 248:         $items[$n]['category']  = (string)$element->genre->catch;
 249:         $items[$n]['open']      = (string)$element->open;
 250:         $items[$n]['close']     = (string)$element->close;
 251:         $items[$n]['address']   = (string)$element->address;
 252:         $items[$n]['image']     = (string)$element->photo->pc->l;
 253:         $items[$n]['latitude']  = (double)$element->lat;
 254:         $items[$n]['longitude'] = (double)$element->lng;
 255:         $items[$n]['description'] =<<< EOT
 256: <span class="small"><a href="{$items[$n]['url']}" target="_blank">{$items[$n]['title']}</a><br />{$items[$n]['address']}<br />営業時間:{$items[$n]['open']}/定休日:{$items[$n]['close']}<br /><img src="{$items[$n]['image']}" /></span>
 257: EOT;
 258:         $n++;
 259:     }
 260: 
 261:     return array($n, '', $url);
 262: }

WebAPIを呼び出して結果を受け取るのはユーザー関数 searchCafe である。結果は配列変数 $items に格納する。
その他のプログラムの流れは、「PHPで電源・WiFi利用可能店舗を検索する」とほぼ同じである。

参考サイト

(この項おわり)
header