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

サンプル・プログラム
stationCongestion.php | サンプル・プログラム本体。 |
.pahooEnv | クラウドサービスを利用するためのアカウント情報などを記入する .env ファイル。 使い方は「各種クラウド連携サービス(WebAPI)の登録方法」を参照。include_path が通ったディレクトリに配置すること。 |
pahooGeoCode.php | 住所・緯度・経度に関わるクラス pahooGeoCode。 使い方は「PHPで住所・ランドマークから最寄り駅を求める」「PHPで住所・ランドマークから緯度・経度を求める」などを参照。include_path が通ったディレクトリに配置すること。 |
pahooCalendar.php | 暦・潮位計算クラス pahooCalendar。 暦・潮位計算クラスの使い方は「PHPで二十四節気・七十二候一覧を作成」「PHPで月齢を計算」「PHPで日出没・月出没・月齢・潮を計算」「PHPで潮位を計算する」などを参照。include_path が通ったディレクトリに配置すること。 |
pahooInputData.php | データ入力に関わる関数群。 使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
バージョン | 更新日 | 内容 |
---|---|---|
1.2.0 | 2025/08/13 | .pahooEnv 導入 |
1.1.0 | 2025/07/05 | jQuery, jqPlot, Datepickerのバージョンアップ |
1.0.0 | 2024/05/11 | 初版 |
バージョン | 更新日 | 内容 |
---|---|---|
6.5.0 | 2025/06/14 | GoogleMaps JavaScript APIの変更に対応 |
6.4.0 | 2025/03/01 | makeYOLP_GeoSelectCategory()--引数$flagWorld追加 |
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 |
バージョン | 更新日 | 内容 |
---|---|---|
4.5.1 | 2025/05/31 | deg2ddmm(), deg2hhmm() 不具合修正 |
4.5.0 | 2024/03/17 | ヒジュラ暦メソッドを追加 |
4.4.1 | 2024/03/17 | getCabinetOfficeHolidayTable() -- bug-fix |
4.4.0 | 2024/02/25 | 内閣府の祝日表を参照できるようにした |
4.3.2 | 2023/02/11 | getSolarTerm72() 表記改訂:水澤腹堅→水沢腹堅 |
バージョン | 更新日 | 内容 |
---|---|---|
1.8.1 | 2025/03/15 | validRegexPattern() -- debug |
1.8.0 | 2024/11/12 | validRegexPattern() 追加 |
1.7.0 | 2024/10/09 | validURL() validEmail() 追加 |
1.6.0 | 2024/10/07 | isButton() -- buttonタグに対応 |
1.5.0 | 2024/01/28 | exitIfExceedVersion() 追加 |
サンプル・プログラムの流れ(メイン)

準備:PHP の https対応


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

これで準備は完了だ。
準備: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 = '';
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でクラスを使ってテキストの読みやすさを調べる」を参照されたい。
準備:地図サービスの選択
stationCongestion.php
77: // 地図描画サービスの選択
78: // 0:Google
79: // 2:地理院地図・OSM
80: define('MAPSERVICE', 0);
81:
82: // 住所検索サービスの選択
83: // 0:Google
84: // 1:Yahoo!ジオコーダAPI
85: // 11:HeartRails Geo API
86: // 12:OSM Nominatim Search API
87: // 13:国土地理院ジオコーディングAPI
88: define('GEOSERVICE', 0);
89:
90: // 逆ジオコーディングサービスの選択
91: // 0:Google
92: // 1:Yahoo!JAPAN
93: // 11:HeartRails Geo API
94: // 21:簡易ジオコーディングサービス
95: define('REVGEOSERVICE', 0);
住所検索サービスは、Google、Yahoo!JAPAN、HeartRails Geo APIから選べる。あらかじめ、定数 GEOSERVICE に値を設定すること。
逆ジオコーディングサービスは、Google、Yahoo!JAPAN、HeartRails Geo API、簡易ジオコーディングサービスから選べる。あらかじめ、定数 REVGEOSERVICE に値を設定すること。
準備: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: }
準備:pahooInputData 関数群

また、各種クラウドサービスに登録したときに取得するアカウント情報、アプリケーションパスワードなどを登録した .pahooEnv ファイルから読み込む関数 pahooLoadEnv を備えている。こちらについては、「各種クラウド連携サービス(WebAPI)の登録方法」をご覧いただきたい。
RapidAPI NAVITIME API
APIキーと利用機能をHTTPヘッダで渡し、各種パラメータをGET渡しすることで、JSON形式の応答を得ることができる。
利用にはRapidAPIのAPIキー(無償)が必要で、その入手方法は「RapidAPI - 各種WebAPIの登録方法」を参照されたい。
NAVITIME APIの一覧と利用料金は https://api-sdk.navitime.co.jp/api/specs/description/about_navitime_api.html をご覧いただきたい。月間500アクセスまでは無料で利用できる。
stationCongestion.php
427: // RapidAPIキー
428: // 取得方法 https://www.paho.org/e-soul/webtech/php06/php06-01-02.shtm#RapidAPI
429: // .pahooEnv ファイルもしくは下記定数に直接記入する.
430: public $RAPID_API_KEY = '';
解説:最寄駅検索
URL | |
---|---|
https://navitime-transport.p.rapidapi.com/transport_node/around | |
HTTPヘッダ名 | 値 |
X-RapidAPI-Host | navitime-transport.p.rapidapi.com |
X-RapidAPI-Key | APIキー |
フィールド名 | 要否 | 内 容 |
---|---|---|
coord | 必須 | 最寄駅を取得したい緯度,経度(カンマ区切り) |
type | 省略可能 | 交通機関タイプ:station 鉄道駅,airport 空港,port 港,busstop 路線バスのバス停(要契約), shuttle_busstop 空港連絡バスのバス停, highway_busstop 高速バスのバス停(要契約) |
limit | 省略可能 | 応答の上限件数【デフォルト 10/最大 30】 |
term | 省略可能 | 応答待ち時間(秒)【デフォルト 60/最大 1440】 |
datum | 省略可能 | 測地系(wgs84またはtokyo)【デフォルト wgs84】 |
walk_speed | 省略可能 | 歩行速度(km/h)【デフォルト 5/最小 3/最大 8】 |
stationCongestion.php
452: /**
453: * 最寄駅検索 - RapidAPI NAVITIME API 2.0
454: * @param double $latitude 緯度(世界測地系)
455: * @param double $longitude 経度(世界測地系)
456: * @param array $items 応答情報を格納する配列
457: * @return array(ヒットした施設数, メッセージ, APIのURL)
458: */
459: function getResultsTransportNodeAround($latitude, $longitude, &$items) {
460: // クラウドサービスの呼び出し
461: $curl = curl_init();
462: $url = 'https://navitime-transport.p.rapidapi.com/transport_node/around?coord=' . $latitude . ',' . $longitude . '&options=by_link';
463: curl_setopt($curl, CURLOPT_URL , $url);
464: curl_setopt($curl, CURLOPT_HEADER, 1) ;
465: curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
466: curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); // 結果を文字列で
467: curl_setopt($curl, CURLOPT_ENCODING, '');
468: curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
469: curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
470: curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
471: curl_setopt($curl, CURLOPT_TIMEOUT, 30);
472: curl_setopt($curl, CURLOPT_HTTPHEADER, [
473: 'X-RapidAPI-Host: navitime-transport.p.rapidapi.com',
474: 'X-RapidAPI-Key: ' . $this->RAPID_API_KEY,
475: ]);
476:
477: $res1 = @curl_exec($curl);
478: $res2 = @curl_getinfo($curl);
479: $errmsg = curl_error($curl);
480:
481: if ($res1 == FALSE) {
482: return array(0, $errmsg, $url);
483: }
484:
485: // JSONデータを配列に格納する
486: $json = substr($res1, $res2['header_size']);
487: $results = json_decode($json);
488:
489: // 応答のデータ構造チェック
490: if (! isset($results->items)) {
491: $errmsg = '検索に失敗しました';
492: return array(0, $errmsg, $url);
493: }
494:
495: // 応答を配列へ代入する.
496: $cnt = 1;
497: foreach ($results->items as $node) {
498: // 記号(A, B, C...)
499: $items[$cnt]['id'] = (string)$this->num2alpha($cnt);
500: // 駅/バス停のノードID
501: $items[$cnt]['nodeId'] = (string)$node->id;
502: // 駅/バス停の読み仮名
503: $items[$cnt]['ruby'] = (string)$node->ruby;
504: // 住所の表示名
505: $items[$cnt]['address_name'] = (string)$node->address_name;
506: // 住所コード
507: $items[$cnt]['address_code'] = (string)$node->address_code;
508: // 緯度
509: $items[$cnt]['latitude'] = (float)$node->coord->lat;
510: // 経度
511: $items[$cnt]['longitude'] = (float)$node->coord->lon;
512: // 検索地点からの距離(メートル)
513: $items[$cnt]['distance'] = (int)$node->distance;
514: // 検索地点からの所要時間(分)
515: $items[$cnt]['time'] = (int)$node->time;
516: // 路線ID
517: $items[$cnt]['linkId'] = (string)$node->link->id;
518: // 路線名称
519: $items[$cnt]['linkName'] = (string)$node->link->name;
520: // 駅名の抽出(nameに路線名が混在しているので)
521: $arr = array();
522: $name = (string)$node->name;
523: if (preg_match('/\s.*?([^\s]*)$/ui', $name, $arr) > 0) {
524: $name = isset($arr[1]) ? $arr[1] : $name;
525: }
526: if (preg_match('/^([^\(]+)/ui', $name, $arr) > 0) {
527: $name = isset($arr[1]) ? $arr[1] : $name;
528: }
529: $items[$cnt]['title'] = $name;
530: // 情報ウィンドウに表示する内容(HTML文)
531: $distance = number_format($items[$cnt]['distance']);
532: $items[$cnt]['description'] =<<< EOT
533: {$items[$cnt]['title']} [{$items[$cnt]['linkName']}] {$distance}m
534: EOT;
535: $cnt++;
536: }
537: return array($cnt - 1, $errmsg, $url);
538: }
応答データには、JSON形式データの前にヘッダ情報が混じっているので、 substr 関数を使ってJSON形式データのみを抽出してから、 json_decode 関数を使ってデコードし、配列 $items に格納する。
解説:混雑度予想
URL | |
---|---|
https://navitime-congestion-prediction.p.rapidapi.com/congestion_prediction/node | |
HTTPヘッダ名 | 値 |
X-RapidAPI-Host | navitime-congestion-prediction.p.rapidapi.com |
X-RapidAPI-Key | APIキー |
フィールド名 | 要否 | 内 容 |
---|---|---|
id | 必須 | 駅/バス停のノードID(最寄駅検索で取得したID) |
date | 必須 | 日付(yyyy-mm-dd形式;本日を含む未来日であること) |
stationCongestion.php
540: /**
541: * 指定した駅の混雑度予想 - RapidAPI NAVITIME API 2.0
542: * @param string $id 駅/バス停のノードID
543: * @param string $date 予想したい年月日(例:2024-05-06;未来日であること)
544: * @param array $items 応答情報を格納する配列
545: * @return array(エラーメッセージ, APIのURL)
546: */
547: function getResultsCongestionNode($id, $date, &$items) {
548: // クラウドサービスの呼び出し
549: $curl = curl_init();
550: $url = 'https://navitime-congestion-prediction.p.rapidapi.com/congestion_prediction/node?id=' . $id . '&date=' . $date;
551: curl_setopt($curl, CURLOPT_URL , $url);
552: curl_setopt($curl, CURLOPT_HEADER, 1) ;
553: curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
554: curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); // 結果を文字列で
555: curl_setopt($curl, CURLOPT_ENCODING, '');
556: curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
557: curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
558: curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
559: curl_setopt($curl, CURLOPT_TIMEOUT, 30);
560: curl_setopt($curl, CURLOPT_HTTPHEADER, [
561: 'X-RapidAPI-Host: navitime-congestion-prediction.p.rapidapi.com',
562: 'X-RapidAPI-Key: ' . $this->RAPID_API_KEY,
563: ]);
564:
565: $res1 = @curl_exec($curl);
566: $res2 = @curl_getinfo($curl);
567: $errmsg = curl_error($curl);
568:
569: if ($res1 == FALSE) {
570: return array(0, $errmsg, $url);
571: }
572:
573: // JSONデータを配列に格納する
574: $json = substr($res1, $res2['header_size']);
575: $results = json_decode($json);
576:
577: // 応答のデータ構造チェック
578: if (! isset($results->items)) {
579: $errmsg = '検索に失敗しました';
580: return array(0, $errmsg, $url);
581: }
582:
583: // 応答を配列へ代入する.
584: $cnt = 1;
585: foreach ($results->items[0]->congestions as $node) {
586: $dt = $node->time;
587: if (preg_match('/T([0-9]+)\:/i', (string)$node->time, $arr) > 0) {
588: $hour = (int)($arr[1]);
589: if ($hour <= 2) {
590: $hour += 24;
591: }
592: $items[$hour] = (float)($node->prediction_rate);
593: }
594: $cnt++;
595: }
596: return array($cnt - 1, $errmsg, $url);
597: }
応答データには、JSON形式データの前にヘッダ情報が混じっているので、 substr 関数を使ってJSON形式データのみを抽出してから、 json_decode 関数を使ってデコードし、配列 $items に格納する。
stationCongestion.php
674: <td style="text-align:center;">{$val['id']}</td>
675: <td><div class="station" onClick="getResultscongestionNode('{$val['nodeId']}')">{$val['title']}</div></td>
676: <td>{$val['linkName']}</td>
677: <td style="text-align:right;">{$distance}</td>
stationCongestion.php
165: <script>
166: /**
167: * 駅名をクリックしたら,nodeIdを代入し,submitする→混雑度予想処理に入る.
168: * @param string idNode 駅/バス停のノードID
169: * @return なし
170: */
171: function getResultscongestionNode(idNode) {
172: document.getElementById('nodeId').value = idNode;
173: myform.submit();
174: }
175: </script>
まず初めに最寄駅検索を行い、そこで得られたノードID($val['nodeId'])を、一覧表の駅名をクリックするとJavaScript関数 getResultscongestionNode を呼び出すようにする。
JavaScript関数 getResultscongestionNode では、受け取ったノードIDをDOMオブジェクト nodeId(実体はhidden属性をもったテキストボックス)に格納し、submitすることで、このページを再読み込みしたことを同じ動きになる。
stationCongestion.php
711: $json = json_encode($items);
712: $html =<<< EOT
713: <body>
714: {$jsmap}
715: <h2>{$title} {$version}</h2>
716: <form name="myform" method="post" action="{$myself}" enctype="multipart/form-data">
717: 検索キー <input type="text" name="query" size="30" value="{$spot['query']}">
718: <input type="submit" id="exec" name="exec" value="キーワード検索">
719: <input type="submit" id="map" name="map" value="地図検索">
720: <input type="submit" id="clear" name="clear" value="リセット">
721: {$str_radio}<br>
722: 年月日 <input class="datepicker" type="text" id="yyyymmdd" name="yyyymmdd" size="10" value="{$date}" >
723:
724: <input type="hidden" id="latitude" name="latitude" value="{$spot['latitude']}" >
725: <input type="hidden" id="longitude" name="longitude" value="{$spot['longitude']}" >
726: <input type="hidden" id="zoom" name="zoom" value="{$spot['zoom']}" >
727: <input type="hidden" id="type" name="type" value="{$spot['type']}" >
728: <input type="hidden" id="nodeId" name="nodeId" value="">
729: <input type="hidden" id="mode" name="mode" value="{$mode}">
730: <textarea style="display:none" id="json" name="json">{$json}</textarea>
その他の使用クラウド連携、JavaScriptライブラリなど
日付をカレンダーから入力するJavaScriptライブラリ jQuery UI:Datepicker の使い方は、「PHPで日付入力:カレンダーから選択」をご覧いただきたい。
棒グラフ描画に使ったJavaScriptライブラリ jqPlot の使い方は、「PHPでNHK政治意識月例調査をグラフ表示」をご覧いただきたい。
参考サイト
- RapidAPI NAVITIME API
- RapidAPI - 各種WebAPIの登録方法:ぱふぅ家のホームページ
- PHPで住所・ランドマークから緯度・経度を求める:ぱふぅ家のホームページ
- PHPで緯度・経度から住所を求める:ぱふぅ家のホームページ
- PHPで住所・ランドマークから最寄り駅を求める
- PHPで日付入力:PHPで日付入力:カレンダーから選択:ぱふぅ家のホームページ
- PHPでNHK政治意識月例調査をグラフ表示:ぱふぅ家のホームページ
(2025年8月13日).pahooEnv 導入
(2025年7月5日)jQuery, jqPlot, Datepickerのバージョンアップ.
(2025年6月14日)GoogleMaps JavaScript APIの変更に対応した.