##各種リファレンス
###GoogleMaps
Google Maps API> ウェブ向け > Maps JavaScript API > スタートガイド
Google Maps API> ウェブ向け > Maps JavaScript API > マーカー
###JavaScript
###PHP
foreach
if
制御構造に関する別の構文
return
htmlspecialchars
require_once
number_format
isset
is_object
代数演算子
filter_input
filter_input_array
sprintf
simplexml_load_file
is_null
ceil
http_build_query
implode
##ソースコード
index.php
<?php
/**
* index.php
*
* @since 2016/08/06
*/
require_once './Hpepper.class.php';
/**
* エスケープ
* これを通さずに出力すると、XSS脆弱性で任意のJavaScriptが実行されてしまう。
*
* @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();
// ドキュメントの頭で、echo しない。
// ここで echo すると、<html> tagよりも前で文字列を出力してしまい、html 文法に違反する。
?>
<!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: 300px;
}
.shop {
margin-bottom: 2em;
}
.shop > div {
border: 1px solid #CCC;
padding: 1em;
}
</style>
</head>
<body>
<div class="container">
<h1>ホットペッパーAPIサンプル</h1>
<form method="get">
<div class="row">
<div class="col-md-4">
<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>
<div class="col-md-4">
<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>
<div class="col-md-4">
<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>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<button type="submit" class="btn btn-primary">検索</button>
</div>
</div>
</div>
</form>
<?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: ?>
<?php $i = 0; ?>
<?php foreach ($restaurants->shop as $rest) : ?>
<?php if ($i % 2 == 0): ?>
<div class="row">
<?php endif; ?>
<div class="col-md-6 shop">
<div>
<dl>
<dt>ID</dt>
<dd><?= h($rest->id); ?></dd>
<dt>店名</dt>
<dd><?= h($rest->name); ?></dd>
<dt>ジャンル</dt>
<dd><?= h($rest->genre->name); ?></dd>
<dt>所在地</dt>
<dd><?= h($rest->address); ?></dd>
</dl>
<div class="map" data-lat="<?= h($rest->lat); ?>" data-lng="<?= h($rest->lng); ?>">
</div>
</div>
</div>
<?php if ($i % 2 == 1 || count($restaurants->shop) - 1 == $i): ?>
</div>
<?php endif; ?>
<?php $i++; ?>
<?php endforeach; ?>
<div class="row">
<div class="col-md-12">
<ul class="pagination pagination-sm no-margin">
<?= Hpepper::pagination($restaurants->results_available); ?>
</ul>
</div>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
<script type="text/javascript" src="//www.google.com/jsapi"></script>
<script type="text/javascript">
var map;
function initMap() {
// map というクラスが付いている要素を複数取得
// 同名IDはドキュメント内に複数設定できないため、クラスでアクセスする。
// MAPがドキュメント内に一つだけ表示するなら、getElementById() を使えば良い。
// @see https://developer.mozilla.org/ja/docs/Web/API/Document/getElementsByClassName
var maps = document.getElementsByClassName('map');
// 複数要素全てを処理する
// @see https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for
for (var i = 0; i < maps.length; i++) {
// それぞれの要素につけてれている data-* 属性から lat, lng を取得する
// @see https://developer.mozilla.org/ja/docs/Web/API/Element/getAttribute
var latlng = {
// @see https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/parseFloat
lat: parseFloat(maps[i].getAttribute('data-lat'))
, lng: parseFloat(maps[i].getAttribute('data-lng'))
};
// MAPオブジェクトをそれぞれ生成する
// @see https://developers.google.com/maps/documentation/javascript/tutorial?hl=ja
map = new google.maps.Map(maps[i], {
center: latlng,
scrollwheel: false,
zoom: 16
});
// 各MAPオブジェクトにマーカーを設定する
// @see https://developers.google.com/maps/documentation/javascript/markers?hl=ja#add
new google.maps.Marker({
position: latlng,
map: map
});
}
}
</script>
<script src="//maps.googleapis.com/maps/api/js?key=GOOGLEMAP_API_KEY&callback=initMap&language=ja"></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
);
// @see http://php.net/manual/ja/function.http-build-query.php
$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, '', '&');
$arr[] = sprintf($html, '', $query, '最初');
$params['start'] = $start - self::$rowCount;
$query = http_build_query($params, '', '&');
$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, '', '&');
$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, '', '&');
$arr[] = sprintf($html, '', $query, '次へ');
$params['start'] = $maxCount;
$query = http_build_query($params, '', '&');
$arr[] = sprintf($html, '', $query, '最終');
}
return implode(PHP_EOL, $arr);
}
}
// PHPのみで構成されるファイルには終了タグ(?>)は不要。
// 終了タグの存在はかえってバグの元になる。
##スクリーンショット