PHP開発日記:しばらく住所録を作ります
作りたいものは1つ決まっているのですが、それまでにいくつかの過程を踏まなければならないようです。
APIの話は一朝一夕ではできる気がしないので、まずは「簡易的な検索エンジン」から取り組んでいきます。
日本郵便の公式ホームページで日本全国の住所録をcsv形式で手に入れることができるので、これを使って日本全国の住所を検索するシステムを作ります。
要件定義
まずは日本全国の住所を入手。
ここから全国の住所が入った「ken_all.zip」を入手し、解凍して「ken_all.csv」を取り出す。カンマで区切られた各項目の説明は以下の通り。
郵便番号データの説明 - 日本郵便より引用。
- 全国地方公共団体コード(JIS X0401、X0402)……… 半角数字
- (旧)郵便番号(5桁)……………………………………… 半角数字
- 郵便番号(7桁)……………………………………… 半角数字
- 都道府県名 ………… 半角カタカナ(コード順に掲載) (注1)
- 市区町村名 ………… 半角カタカナ(コード順に掲載) (注1)
- 町域名 ……………… 半角カタカナ(五十音順に掲載) (注1)
- 都道府県名 ………… 漢字(コード順に掲載) (注1,2)
- 市区町村名 ………… 漢字(コード順に掲載) (注1,2)
- 町域名 ……………… 漢字(五十音順に掲載) (注1,2)
- 一町域が二以上の郵便番号で表される場合の表示 (注3) (「1」は該当、「0」は該当せず)
- 小字毎に番地が起番されている町域の表示 (注4) (「1」は該当、「0」は該当せず)
- 丁目を有する町域の場合の表示 (「1」は該当、「0」は該当せず)
- 一つの郵便番号で二以上の町域を表す場合の表示 (注5) (「1」は該当、「0」は該当せず)
- 更新の表示(注6)(「0」は変更なし、「1」は変更あり、「2」廃止(廃止データのみ使用))
- 変更理由 (「0」は変更なし、「1」市政・区政・町政・分区・政令指定都市施行、「2」住居表示の実施、「3」区画整理、「4」郵便区調整等、「5」訂正、「6」廃止(廃止データのみ使用)
この中で「3.郵便番号」「7.都道府県名(漢字)」「4.都道府県名(半角カナ)」「8.市区町村名(漢字)」「5.市区町村名(半角カナ)」「9.町域名(漢字)」「6.町域名(半角カナ)」を取り出し、取り込み用のPHPファイルを作ってMySQLに取り込む。余力があればcsvファイルをアップロードするボタンを作って、「ローカル環境から仮想環境へファイルをアップロード→それを取り込み」という機能もいいかもしれない。取り込むかどうかの判断が難しそうだけど…。
なお、町域名に「以下に掲載がない場合」と入っているレコードも存在している。これについては取り込みの段階で弾くようにしたい。
取り込み先となるMySQLのデータベースとテーブルを作成する。
データベース名:address
テーブル名:address
テーブル構成
addno varchar(7) primary key…郵便番号、主キーとする
add1 varchar(255)…都道府県名(漢字)
add1kana varchar(255)…都道府県名(半角カナ)
add2 varchar(255)…市区町村名(漢字)
add2kana varchar(255)…市区町村名(半角カナ)
add3 varchar(255)…町域名(漢字)
add3kana varchar(255) …町域名(半角カナ)
インデックスは考えずに作成。
次にPHP側を作成。
昨日までの学習内容を参考にconfig.phpを作成し、定数の設定を行う。
<?php
//Config.php
// 住所録用定数
define('DSN','mysql:dbname=address;host=localhost');
define('DB_USER','user');
define('DB_PASS','aaaa');
define('SITE_URL','http:192.168.33.11:8000');error_reporting(E_ALL & ~E_NOTICE);
今回はセッションは使わない予定なので、今のところは設定していない。
これまでと同様、MySQL接続用のヘルパーファイルも作成。
<?php
//db_helper.php
function get_db_connect(){
try {
$dsn=DSN;
$user=DB_USER;
$password=DB_PASS;
$dbh=new PDO($dsn,$user,$password);
} catch (PDOException $e) {
echo $e->getMessage();
die();
}
$dbh->setAttribute(PDO::ATTR_ERRMODE,ERRMODE_EXCEPTION);
return $dbh
}
HTML表示用の関数も別のヘルパーファイルに作成する。
<?php
//extra_helper.php
function html_escape($word){
return htmlspecialchars($word,ENT_QUOTES,'UTF-8');
}
とりあえずはこれだけ、必要があれば適宜追加していく。
まずはcsv取り込み用のページを作る。
定数に以下のフラグとなる定数を設定し、index.phpを開いたときにこの定数をチェック→csv取り込みに飛ぶか検索に飛ぶかを判断する。
//config.php
//住所録設定関連
define('GETCSV','ON'); //ON→CSV取り込み、OFF→検索
index.phpには以下のように記述。
<?php
//index.php
//設定&関数読み込み
require_once('config.php');
require_once('./helpers/db_helper.php');
require_once('./helpers/extra_helper.php');if (GETCSV==='ON') {
header('Location:'.SITE_URL.'csvget.php');
exit();
} else {
header('Location:'.SITE_URL.'search.php');
exit();
}
フラグに応じてリダイレクト先を変えるようにした。
いよいよcsvget.phpを作成する。csvget.phpのディレクトリに「csv」というフォルダを作り、そこに先ほど取得したken_all.csvをアップロードしてある。
<?php
require_once('config.php');
require_once('./helper/db_helper.php');
require_once('./helper/extra_helper.php');
//csv読み込み処理
$file=@fopen('./csv/KEN_ALL.CSV','r') or die('ファイルを開けませんでした');
//var_dump($file);
flock($file,LOCK_SH);
//とりあえず画面に出してみよう
while (!feof($file)) {
$line=fgets($file);
echo '<p>'.$line.'</p>';
}
flock($file,LOCK_UN);
fclose($file);
ファイル名については大文字小文字の判定までしているので、ファイル名に合わせて書く。登録の前にとりあえず画面に表示を…と思ったが、文字化けでひどい有様に。
今まで文字コードはUTF-8だったけど、今回はなんだか違うような気がする…。
明日はこの文字化けの解消法を探る。画面に出すところまではできているので、文字化けさえ解消できれば登録もすぐ出来そう。