7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

(XML版)ホットペッパーAPIからレストラン検索するサンプル

Last updated at Posted at 2016-08-06

某QAサイトで一部の方に大人気な質問者がw
なんか、よくわからん理由で xml形式での取得にこだわっているらしいので、XML版投下。

単純に json_encode を simplexml_load_file に変えるだけでは動かない謎仕様w

ホットペッパーAPI

というのも、レスポンスの構造が json と xml で違っているではありませんか!
図らずもホットペッパーAPIのバグを発見w
リファレンス通りなのは、xml の方で、 json のレスポンスが間違いですね。

2016/08/08
無駄に機能充実w
多少DRYに。

2016/09/15
なんか、別人なんだろうけど、せっかくだから、足してみた。
どんなページを作りたいのかいまいち書かれていないので、本人がやりたいことなのかわからないけど…
google map apiのマッシュアップ

index.php
<?php
/**
 * index.php
 *
 * @since 2016/08/06
 */
require_once './Hpepper.class.php';

/**
 * エスケープ
 * @param string $string
 * @return string
 */
function h($string)
{
	return htmlspecialchars($string, ENT_QUOTES, 'utf-8');
}

// 料理カテゴリ
$food_category = Hpepper::getFoodCategory();

// 予算
$budget = Hpepper::getBudget();

// クレジットカード
$credit_card = Hpepper::getCreditCard();

// 大サービスエリア
$large_service_area = Hpepper::getLargeServiceArea();

// サービスエリア
$service_area = Hpepper::getServiceArea();

// レストラン検索
$restaurants = Hpepper::getRestaurants();
?>
<!DOCTYPE HTML>
<html lang="ja">
	<head>
		<meta charset="UTF-8">
		<title>ホットペッパーAPIテスト(アホでも設置するだけで動く)</title>
		<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
		<style type="text/css">
			#map{
				height: 400px;
			}
		</style>
	</head>
	<body>
		<div class="container">
			<h1>ホットペッパーAPIサンプル</h1>

			<div class="row">
				<div class="col-md-6">
					<form method="get">
						<div class="form-group">
							<label for="food_category">料理カテゴリ</label>
							<select class="form-control" name="food" id="food_category">
								<option value="">料理カテゴリ</option>
								<?php foreach ($food_category->food_category as $food_category) : ?>
									<?php if ($food_category->code == filter_input(INPUT_GET, 'food')): ?>
										<option value="<?= h($food_category->code); ?>" selected="selected">
											<?= h($food_category->name); ?>
										</option>
									<?php else: ?>
										<option value="<?= h($food_category->code); ?>">
											<?= h($food_category->name); ?>
										</option>
									<?php endif; ?>
								<?php endforeach; ?>
							</select>
						</div>

						<div class="form-group">
							<label for="budget">予算</label>
							<select class="form-control" name="budget" id="service_area">
								<option value="">予算</option>
								<?php foreach ($budget->budget as $budget) : ?>
									<?php if ($budget->code == filter_input(INPUT_GET, 'budget')): ?>
										<option value="<?= h($budget->code); ?>" selected="selected">
											<?= h($budget->name); ?>
										</option>
									<?php else: ?>
										<option value="<?= h($budget->code); ?>">
											<?= h($budget->name); ?>
										</option>
									<?php endif; ?>
								<?php endforeach; ?>
							</select>
						</div>

						<div class="form-group">
							<label for="credit_card">クレジットカード</label>
							<select class="form-control" name="credit_card" id="credit_card">
								<option value="">クレジットカード</option>
								<?php foreach ($credit_card->credit_card as $credit_card) : ?>
									<?php if ($credit_card->code == filter_input(INPUT_GET, 'credit_card')): ?>
										<option value="<?= h($credit_card->code); ?>" selected="selected">
											<?= h($credit_card->name); ?>
										</option>
									<?php else: ?>
										<option value="<?= h($credit_card->code); ?>">
											<?= h($credit_card->name); ?>
										</option>
									<?php endif; ?>
								<?php endforeach; ?>
							</select>
						</div>

						<div class="form-group">
							<label for="large_service_area">大サービスエリア</label>
							<select class="form-control" name="large_service_area" id="large_service_area">
								<option value="">大サービスエリア</option>
								<?php foreach ($large_service_area->large_service_area as $large_service_area) : ?>
									<?php if ($large_service_area->code == filter_input(INPUT_GET, 'large_service_area')): ?>
										<option value="<?= h($large_service_area->code); ?>" selected="selected">
											<?= h($large_service_area->name); ?>
										</option>
									<?php else: ?>
										<option value="<?= h($large_service_area->code); ?>">
											<?= h($large_service_area->name); ?>
										</option>
									<?php endif; ?>
								<?php endforeach; ?>
							</select>
						</div>

						<div class="form-group">
							<label for="service_area">サービスエリア</label>
							<select class="form-control" name="service_area" id="service_area">
								<option value="">サービスエリア</option>
								<?php foreach ($service_area->service_area as $pref) : ?>
									<?php if ($pref->code == filter_input(INPUT_GET, 'service_area')): ?>
										<option value="<?= h($pref->code); ?>" selected="selected">
											<?= h($pref->name); ?>
										</option>
									<?php else: ?>
										<option value="<?= h($pref->code); ?>">
											<?= h($pref->name); ?>
										</option>
									<?php endif; ?>
								<?php endforeach; ?>
							</select>
						</div>

						<div class="form-group">
							<label for="name_kana">店名 or ふりがな</label>
							<input class="form-control" type="text" name="name_kana" id="name_kana" value="<?= h(filter_input(INPUT_GET, 'name_kana')); ?>" />
						</div>

						<div class="form-group">
							<label for="keyword">フリーワード</label>
							<input class="form-control" type="text" name="keyword" id="keyword" value="<?= h(filter_input(INPUT_GET, 'keyword')); ?>" />
						</div>

						<div class="form-group">
							<button type="submit" class="btn btn-primary">検索</button>
						</div>
					</form>
				</div>
			</div>
			<?php if (is_object($restaurants)): ?>

				<p>検索結果 <?= h(number_format((int) $restaurants->results_available)); ?> 件</p>

				<?php if (isset($restaurants->error)): ?>
					<div>
						<?php foreach ($restaurants->error as $err) : ?>
							<h2><?= $err->code; ?></h2>
							<p><?= $err->message; ?></p>
						<?php endforeach; ?>
					</div>
				<?php else: ?>
					<table class="table table-condensed">
						<thead>
							<tr>
								<th>id</th>
								<th>name</th>
								<th>category</th>
								<th>address</th>
							</tr>
						</thead>
						<tbody>
							<?php foreach ($restaurants->shop as $rest) : ?>
								<tr class="shop" data-lat="<?= h($rest->lat); ?>" data-lng="<?= h($rest->lng); ?>">
									<td><?= h($rest->id); ?></td>
									<td>
										<a href="detail.php?id=<?= h($rest->id); ?>"><?= h($rest->name); ?></a>
									</td>
									<td><?= h($rest->genre->name); ?></td>
									<td><?= h($rest->address); ?></td>
								</tr>
							<?php endforeach; ?>
						</tbody>
					</table>

					<ul class="pagination pagination-sm no-margin">
						<?= Hpepper::pagination($restaurants->results_available); ?>
					</ul>
				<?php endif; ?>
			<?php endif; ?>
			<div class="row">
				<div class="col-md-12">
					<div id="map">

					</div>
				</div>
			</div>
		</div>
		<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
		<script type="text/javascript">
			function initMap() {
				var dom = document.getElementById('map');
				var map = new google.maps.Map(dom, {
					center: {
						lat: 35.685175
						, lng: 139.7527995
					},
					scrollwheel: false,
					zoom: 8
				});

				var shops = document.getElementsByClassName('shop');
				if (shops.length === 0) {
					return;
				}

				var bounds = new google.maps.LatLngBounds();

				for (var i = 0; i < shops.length; i++) {
					var marker = new google.maps.Marker({
						position: {
							lat: parseFloat(shops[i].getAttribute('data-lat'))
							, lng: parseFloat(shops[i].getAttribute('data-lng'))
						},
						map: map
					});
					bounds.extend(marker.position);
				}
				map.fitBounds(bounds);
			}
			initMap();
		</script>
	</body>
</html>
detail.php
<?php
/**
 * detail.php
 *
 * @since 2016/09/15
 */
require_once './Hpepper.class.php';

/**
 * エスケープ
 * @param string $string
 * @return string
 */
function h($string)
{
	return htmlspecialchars($string, ENT_QUOTES, 'utf-8');
}

// レストラン検索
$restaurants = Hpepper::getRestaurants();
?>
<!DOCTYPE HTML>
<html lang="ja">
	<head>
		<meta charset="UTF-8">
		<title></title>
		<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
		<style type="text/css">
			#map {
				height: 300px;
			}
		</style>
	</head>
	<body>
		<div class="container">
			<div class="row">
				<div class="col-md-6 col-md-offset-3">
					<p><?= h($restaurants->shop->genre->name); ?></p>
					<p><?= h($restaurants->shop->name); ?></p>
					<p><?= h($restaurants->shop->address); ?></p>
					<p>
						<img src="<?= h($restaurants->shop->logo_image); ?>" alt="" />
					</p>
				</div>
			</div>
			<div class="row">
				<div class="col-md-6 col-md-offset-3">
					<div id="map" data-lat="<?= h($restaurants->shop->lat); ?>" data-lng="<?= h($restaurants->shop->lng); ?>">

					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-md-6 col-md-offset-3">
					<?php var_dump($restaurants); ?>
				</div>
			</div>
		</div>
		<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
		<script type="text/javascript">
			function initMap() {
				var dom = document.getElementById('map');
				var position = {
					lat: parseFloat(dom.getAttribute('data-lat'))
					, lng: parseFloat(dom.getAttribute('data-lng'))
				};
				var map = new google.maps.Map(dom, {
					center: position,
					scrollwheel: false,
					zoom: 14
				});
				var marker = new google.maps.Marker({
					position: position,
					map: map
				});
			}
			initMap();
		</script>
	</body>
</html>
Hpepper.class.php
<?php

/**
 * Hpepper.class.php
 *
 * @since 2016/08/06
 */
class Hpepper
{

	/**
	 * アクセスキー
	 * @var string
	 */
	private static $token = 'APIKEY';

	/**
	 * 1ページに表示する件数
	 * @var int
	 */
	private static $rowCount = 10;

	/**
	 * API問い合わせ
	 * @param string $uri
	 * @param array $query
	 * @return object
	 */
	private static function request($uri, $query = array())
	{
		$query += array(
			'format' => 'xml'
			, 'key' => self::$token
		);
		$url = sprintf("%s?%s", $uri, http_build_query($query));
		$obj = simplexml_load_file($url);
		return $obj;
	}

	/**
	 * 予算リストを取得
	 * @return object
	 */
	public static function getBudget()
	{
		$uri = "http://webservice.recruit.co.jp/hotpepper/budget/v1/";
		return self::request($uri);
	}

	/**
	 * 大サービスエリア
	 * @return object
	 */
	public static function getLargeServiceArea()
	{
		$uri = "http://webservice.recruit.co.jp/hotpepper/large_service_area/v1/";
		return self::request($uri);
	}

	/**
	 * サービスエリアマスタAPI
	 * @return object
	 */
	public static function getServiceArea()
	{
		$uri = "https://webservice.recruit.co.jp/hotpepper/service_area/v1/";
		return self::request($uri);
	}

	/**
	 * 料理カテゴリ
	 * @return object
	 */
	public static function getFoodCategory()
	{
		$uri = "http://webservice.recruit.co.jp/hotpepper/food_category/v1/";
		return self::request($uri);
	}

	/**
	 * クレジットカードマスタAPI
	 * @return object
	 */
	public static function getCreditCard()
	{
		$uri = "http://webservice.recruit.co.jp/hotpepper/credit_card/v1/";
		return self::request($uri);
	}

	/**
	 * レストラン検索
	 * @return object
	 */
	public static function getRestaurants()
	{
		$uri = "http://webservice.recruit.co.jp/hotpepper/gourmet/v1/";
		$query = array(
			'count' => self::$rowCount
		);
		if (!is_null(filter_input_array(INPUT_GET))) {
			$query += filter_input_array(INPUT_GET);
		}
		return self::request($uri, $query);
	}

	/**
	 * ページネーション
	 * @param int $total
	 * @return string
	 */
	public static function pagination($total = 0)
	{
		if ($total == 0) {
			return;
		}
		$start = filter_input(INPUT_GET, 'start', FILTER_VALIDATE_INT);
		if ($start == 0) {
			$start = 1;
		}

		$html = '<li%s><a href="?%s">%s</a></li>';

		//現在の頁
		$curPage = ceil($start / self::$rowCount);
		$iStart = (0 < $curPage - 3) ? $curPage - 3 : 1;

		$pages = ceil($total / self::$rowCount);
		$iMax = ($iStart + 6 > $pages) ? $pages : $iStart + 6;

		$arr = array();
		$params = filter_input_array(INPUT_GET);

		// 先頭ページ
		if ($start != 1) {
			$params['start'] = 1;
			$query = http_build_query($params, '', '&amp;');
			$arr[] = sprintf($html, '', $query, '最初');
			$params['start'] = $start - self::$rowCount;
			$query = http_build_query($params, '', '&amp;');
			$arr[] = sprintf($html, '', $query, '前へ');
		}

		for ($i = $iStart; $i <= $iMax; $i++) {
			$params['start'] = ($i - 1) * self::$rowCount + 1;
			$class = ($params['start'] == $start) ? ' class="active"' : '';
			$query = http_build_query($params, '', '&amp;');
			$arr[] = sprintf($html, $class, $query, $i);
		}

		// 最終ページ
		$maxCount = ($pages - 1) * self::$rowCount + 1;
		if ($start < $maxCount) {
			$params['start'] = $start + self::$rowCount;
			$query = http_build_query($params, '', '&amp;');
			$arr[] = sprintf($html, '', $query, '次へ');
			$params['start'] = $maxCount;
			$query = http_build_query($params, '', '&amp;');
			$arr[] = sprintf($html, '', $query, '最終');
		}

		return implode(PHP_EOL, $arr);
	}

}

localhost_2016-09-15_05-15-15.png

7
7
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?