WebAPI(郵便番号から住所を取得する)を作ってみた。
//どう実装するか?
Webフォームなんかによくある郵便番号を入力すると、自動的に都道府県&市区町村名が入るようなプログラミングを組もうと調べてみたら2通りのやり方があるらしい。
方法その1,郵便局のHP(http://www.post.japanpost.jp/zipcode/download.html)からCSVファイルでダウンロードして、検索プログラムを自分で作る。
自分で実装しないといけない上に、郵便番号は毎月新しいデータが出てくるらしいのでパス!
方法その2,外部のWebAPIを使って実装する。
そのWebサービスが終了したら使えなくなるが、メンテナンスの必要もないので楽。
ただ、SSL(https)に対応、商業フリー、ヨミガナ付きのWebサービスがなかったので、最終的には自分で作る事にしました。
//データベースの構造
郵便番号のデータは、12万3423件もあるので流石にCSVファイルのままで利用するのは無理!
なので、フリーのMySQLというデータベースを使う。テーブルの基本構造は、郵便局からダウンロードしたCSVファイルのまま。
(主キーとして、auto_incrementなidフィールドを追加)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
CREATE TABLE tbl_zip ( id int(11) NOT NULL AUTO_INCREMENT, jis varchar(10) NULL, zip_old varchar(5) NULL, zip varchar(7) NULL, addr1_kana varchar(100) NULL, addr2_kana varchar(100) NULL, addr3_kana varchar(100) NULL, addr1 varchar(100) NULL, addr2 varchar(100) NULL, addr3 varchar(100) NULL, c1 int NULL, c2 int NULL, c3 int NULL, c4 int NULL, c5 int NULL, c6 int NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; |
//レコードの挿入
テーブルが出来たら、12万3423件の郵便番号データを打ち込む。ポイントはauto_incrementのフィールドは指定しない事!
あと、注意するのは一行目はヘッダー情報なので、ignore(無視)オプションを付ける必要がある(手動で一行目を削除してもいい)
1 |
LOAD DATA LOCAL INFILE 'KEN_ALL.CSV' INTO TABLE tbl_zip FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '' LINES STARTING BY '' TERMINATED BY '\r\n' (jis,zip_old,zip,addr1_kana,addr2_kana,addr3_kana,addr1,addr2,addr3,c1,c2,c3,c4,c5,c6); |
コマンドライン接続が出来ない場合には、phpmyadminからインポートする。
//PHPコーディングについて
次は、処理を行うPHPのコーディング
今回のPHPでWebAPIを作る時に特筆すべきなのは、Ajax+JSONPでデータをやりとりするという事です。
と言っても、実装としては簡単で、配列データをjson_encode()でエンコードして、callback関数名を前につけるだけ!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<?php try { $pdo = new PDO('mysql:dbname='. $dsn['dbname'] .";host=" . $dsn['host'], $dsn['user'], $dsn['pass']); } catch (PDOException $e) { exit('データベースに接続できませんでした。' . $e->getMessage()); } $stmt = $pdo->query('SET NAMES utf8'); if (!$stmt) { $info = $pdo->errorInfo(); exit($info[2]); } $zipcode = $_GET["zipcode"]; //セキュリティを考えて、SQL文はプリペアドステートメントで発行。 $stmt = $pdo->prepare('SELECT * FROM tbl_zip WHERE zip = ?'); $stmt->execute(array($zipcode)); if (!$stmt) { $info = $pdo->errorInfo(); exit($info[2]); } while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) { // echo '<p>' . $data['zip'] . ':' . $data['addr1'].$data['addr2']. $data['addr3']. '(' . $data['addr1_kana'].$data['addr2_kana'].$data['addr3_kana'].")</p>\n"; $json[0] = $data['zip']; $json[1] = $data['addr1']; $json[2] = $data['addr2']; $json[3] = $data['addr3']; $json[4] = mb_convert_kana($data['addr1_kana'], 'KV', 'UTF-8'); $json[5] = mb_convert_kana($data['addr2_kana'], 'KV', 'UTF-8'); $json[6] = mb_convert_kana($data['addr3_kana'], 'KV', 'UTF-8'); } header('Content-Type: application/json; charset=UTF-8'); echo $_GET['callback'] . "(" . json_encode($json). ")"; $pdo = null; ?> |
//このWebAPIの使い方
https://example.co.jp/zip/zip.php?zipcode=1050001&callback=a
zipcode=の部分に知りたい郵便番号を入れる。
callback=にはコールバック関数(住所を取得した後に実行したい関数)を入れる。
戻り値は配列で、
arr[0]=郵便番号
arr[1]=都道府県名
arr[2]=市区名
arr[3]=町名
arr[4]=都道府県名カタカナ
arr[5]=市区名カタカナ
arr[6]=町名カタカナ
となります。
//HTMLファイルからの使い方
javascriptだけなので、ローカルでも実行できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"> </script> <form name="form"> <script type="text/javascript"> function fncGetAdd(parm) { if(parm.length != 7) return; $.getJSON( "https://example.co.jp/zip/zip.php?callback=?", { zipcode : parm }, function(json) { $("#pref01").val(json[1]+json[2]+ json[3]); $("#addr01").val(json[4]+ json[5]+ json[6]); } ); } </script> zipcode : <input type="text" id="zip01" size="10" maxlength="8" > <input type="text" id="zip02" size="10" maxlength="8" onKeyUp="fncGetAdd(document.getElementById('zip01').value + document.getElementById('zip02').value);"> <br/> <br/> <input type="text" id="pref01" size="60"><br/> <input type="text" id="addr01" size="60"> |