PHPで携帯電話用のGoogleマップを作成する

(1/1)
今回は、「PHPでGoogleを利用して住所から緯度・経度を求める」の応用で、住所を指定して、携帯電話用のGoogleマップを作成するプログラムをつくってみることにする。

(2021年10月10日)PHP8対応,リファラ・チェック改良など

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

PHPで携帯電話用のGoogleマップを作成する
上図はサンプル・プログラムの画面イメージである。
住所(必須)、目的地、目的地URLを入力し「作成」ボタンをクリックすることで、画面下段のようにGoogleマップ(静止画)と、目的地へのリンクを表示する。そして、これを表示するためのHTMLをtextarea内に表示する。
また、画面の表示幅、表示高、地図の拡大率を指定できるようになっている。

目次

サンプル・プログラム

圧縮ファイルの内容
getGoogleMapStd.phpサンプル・プログラム本体。
pahooGeoCode.php住所・緯度・経度に関わるクラス pahooGeoCode。
使い方は「PHPで住所・ランドマークから最寄り駅を求める」「PHPで住所・ランドマークから緯度・経度を求める」などを参照。include_path が通ったディレクトリに配置すること。

準備:pahooGeoCode クラス

0037: class pahooGeoCode {
0038:     var $items;      //検索結果格納用
0039:     var $error;      //エラーフラグ
0040:     var $hits;       //検索ヒット件数
0041:     var $webapi; //直前に呼び出したWebAPI URL
0042: 
0043:     //Google Cloud Platform APIキー
0044:     //https://cloud.google.com/maps-platform/
0045:     //※Google Maps APIを利用しないのなら登録不要
0046:     var $GOOGLE_API_KEY_1 = '**************************';   //HTTPリファラ用
0047:     var $GOOGLE_API_KEY_2 = '**************************';   //IP制限用
0048: 
0049:     //Yahoo! JAPAN Webサービス アプリケーションID
0050:     //https://e.developer.yahoo.co.jp/register
0051:     //※Yahoo! JAPAN Webサービスを利用しないのなら登録不要
0052:     var $YAHOO_APPLICATION_ID = '*****************************';

地図描画や住所検索を行うために、クラスファイル "pahooGeoCode.php" を使用する。組み込み関数  require_once  を使って読めるディレクトリに配置する。ディレクトリは、設定ファイル php.ini に記述されているオプション設定 include_path に設定しておく。
クラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」を参照されたい。

地図や住所検索として Google を利用するのであれば、Google Cloud Platform APIキー が必要で、その入手方法は「Google Cloud Platform - WebAPIの登録方法」を、Yahoo!JAPAN を利用するのであれば、Yahoo! JAPAN Webサービス アプリケーションIDが必要で、その入手方法は「Yahoo!JAPAN デベロッパーネットワーク - WebAPIの登録方法」を、それぞれ参照されたい。

サンプル・プログラムの流れ

PHPで携帯電話用のGoogleマップを作成する

解説:GoogleMaps staticmap

0999: /**
1000:  * GoogleMaps staticmapの画像URLを求める
1001:  * @param   array  $items情報配列
1002:  * @return  string 画像URL
1003: */
1004: function getStaticMap($items) {
1005:     $key = $this->GOOGLE_API_KEY_1;
1006: 
1007:     return "https://maps.googleapis.com/maps/api/staticmap?center={$items['latitude']},{$items['longitude']}&markers=color:red%7Clabel:A%7C{$items['latitude']},{$items['longitude']}&zoom={$items['zoom']}&size={$items['width']}x{$items['height']}&key={$key}";
1008: }

携帯電話用の画像URLは、メソッド getStaticMap を使って取得する。

解説:パラメータの取得

0458: /**
0459:  * Google Geocoding API(V3)+ジオどすII APIを用いて
0460:  * 住所・駅名の緯度・経度を検索
0461:  *
0462:  * @param   string $query検索キーワード(UTF-8)
0463:  * @return  array(intヒットした地点数,string WebAPI)
0464: */
0465: function searchPoint2($query) {
0466:     static $pat1 = '/E(\d+\.?\d*)N(\d+\.?\d*)/i';
0467:     static $pat2 = '/E(\d+)\.(\d+)\.(\d+)\.(\d+)N(\d+)\.(\d+)\.(\d+)\.(\d+)/i';
0468: 
0469:     unset($this->items);
0470:     $this->items = array();
0471:     $this->hits = 0;
0472: 
0473:     //緯度・経度表記(1)
0474:     if (preg_match($pat1$query) > 0) {
0475:         list($this->items[1]['latitude'], $this->items[1]['longitude']) =
0476:             $this->parse_geo($query);
0477:         $this->items[1]['address'] = '';
0478:         $this->hits = 1;
0479: 
0480:     //緯度・経度表記(2)
0481:     } else if (preg_match($pat2$query) > 0) {
0482:         list($this->items[1]['latitude'], $this->items[1]['longitude']) =
0483:             $this->parse_geo($query);
0484:         $this->items[1]['address'] = '';
0485:         $this->hits = 1;
0486:     }
0487:     //Google Geocoding API使用
0488:     if ($this->hits == 0) {
0489:         $n = $this->getPointsV3_all($query$this->items);
0490:         if ($n == FALSE) {
0491:             $this->error  = TRUE;
0492:             $this->errmsg = 'Google Geocoding APIにトラブル発生';
0493:             $this->hits = 0;
0494:         } else if ($n == 0) {
0495:             $this->error  = TRUE;
0496:             $this->errmsg = '検索結果がない';
0497:             $this->hits = 0;
0498:         } else {
0499:             $this->hits = $n;
0500:         }
0501:     }
0502: 
0503:     return array($this->hits$this->webapi);
0504: }

受け取った住所を緯度・経度に変換するメソッド searchPoint2 については、「PHPでGoogleを利用して住所から緯度・経度を求める」で作成したものと同じなので解説を割愛する。
ここでは、パラメータを受け取る際のバリデーション処理について説明する。

本プログラムは、HTML FORMでパラメータを入力し、自分自身(スクリプト)を呼び出すものであるが、悪意のある第三者が悪意のあるパラメータを使ってスクリプトを呼び出すかもしれない。そこで、パラメータがプログラムに悪影響を及ぼさないかどうかチェックする必要がある。
データのバリデーション機能は、PEARのようなフレームワークに用意されているのだが、ここでは、整数をチェックする getParam_validateInt と文字列をチェックする getParam_validateStr という2つのユーザー関数を用意することにした。

0179: /**
0180:  * 指定したパラメータを取り出す(整数バリデーション付き)
0181:  * @param   string $key  パラメータ名(省略不可)
0182:  * @param   int    $def  デフォルト値(省略可)
0183:  * @param   int    $min  最小値(省略可)
0184:  * @param   int    $max  最大値(省略可)
0185:  * @return  int値/FALSE
0186: */
0187: function getParam_validateInt($key$def='', $min=0, $max=9999) {
0188:     //パラメータの存在チェック
0189:     if (isset($_GET[$key]))     $param = $_GET[$key];
0190:     else if (isset($_POST[$key]))   $param = $_POST[$key];
0191:     else                            $param = $def;
0192:     //整数チェック
0193:     if (preg_match('/^[0-9\-]+$/', $param) == 0)    return FALSE;
0194:     //最小値・最大値チェック
0195:     if ($param < $min || $param > $max)             return FALSE;
0196: 
0197:     return $param;
0198: }

まず、整数値をチェックするユーザー関数 getParam_validateInt であるが、
  1. パラメータが存在するかどうか
  2. 整数かどうか
  3. 指定した最大値・最小値の範囲にあるかどうか
の3点をチェックするものである。これらのチェックをクリアしたものは整数値そのものを、いずれかで異常が発生した場合にはデフォルト値 $def を返す。

「整数かどうか」のチェックでは、組み込み関数  is_int  を使おうと考えたが、HTML FORM からの入力を判定できない(文字列と認識してしまう)ため、 preg_match  により正規表現で判定することにした。

0200: /**
0201:  * 指定したパラメータを取り出す(文字列バリデーション付き)
0202:  * @param   string $key  パラメータ名(省略不可)
0203:  * @param   bool   $auto TRUE=自動コード変換あり/FALSE=なし(省略時:TRUE)
0204:  * @param   int    $def  デフォルト値(省略可)
0205:  * @param   int    $min  文字列長・最短(省略可)
0206:  * @param   int    $max  文字列長・最長(省略可)
0207:  * @return  string文字列/FALSE
0208: */
0209: function getParam_validateStr($key$auto=TRUE$def='', $min=3, $max=80) {
0210:     //パラメータの存在チェック
0211:     if (isset($_GET[$key]))     $param = $_GET[$key];
0212:     else if (isset($_POST[$key]))   $param = $_POST[$key];
0213:     else                            $param = $def;
0214:     if ($auto)  $param = mb_convert_encoding($paramINTERNAL_ENCODING, 'auto');
0215:     $param = htmlspecialchars(strip_tags($param));       //タグを除く
0216:     //文字列長チェック
0217:     $len = mb_strlen($param);
0218:     if ($len < $min || $len > $max)     return FALSE;
0219: 
0220:     return $param;
0221: }

次に、文字列をチェックするユーザー関数 getParam_validateStr であるが、
  1. パラメータが存在するかどうか
  2. 指定した最長値・最短値の範囲にあるかどうか
の2点をチェックするとともに、文字コードを指定されたコードに変換する処理を加えている。これらのチェックをクリアしたものは、関数  strip_tags  によりタグを取り除き、関数  htmlspecialchars  により特殊文字を変換してリターンする。
チェック工程のいずれかで異常が発生した場合には '' を返す。

参考サイト

(この項おわり)
header