#郵便番号か住所で検索
##内容
郵便番号または都道府県を選択し市町村を入力すると
郵便のデータが検索できます。
10件を超えた場合に”前へ”、”次へ”を押すと各々のページに飛ぶようになっています。
SQL脆弱性があると思いますが、今のところこのまま学習を進めていきます。
// 変数を設定
$post_num ='';//郵便番号
$area ='';//都道府県選択
$city ='';//市町村
$town ='';//県域
$error1 = [];//エラー文
$error2 = [];//エラー文
$user_data = [];
$abc_data = [];
$query = '';
$host = 'localhost';
$username = '';
$passwd = '';
$dbname = '';
$link= mysqli_connect($host, $username, $passwd, $dbname);
$page = 1;
$count = '';//トータル件数
$totalpage = ceil($count/ 10);//切り上げ
##変数が存在するかを確認
//どちらかに値が入っていた場合
if(isset($_GET['post_num']) === true || isset($_GET['area']) === true) {
//変数を代入する
if(isset($_GET['post_num']) === true) {
$post_num = $_GET['post_num'];
}
if(isset($_GET['area']) === true) {
$area = $_GET['area'];
}
if(isset($_GET['city']) === true) {
$city = $_GET['city'];
}
if(isset($_GET['town']) === true) {
$town = $_GET['town'];
}
if(isset($_GET['page']) === true) {
$page = $_GET['page'];
}
if(isset($_GET['post_num']) === true || isset($_GET['area']) === true)
このif文を書かないと空欄の状態でも変数の確認をしてしまうため、
後述のエラー文が出てしまいます
##空白の削除をします
$post_num = str_replace(array(" "," "),"", $post_num);
$area = str_replace(array(" "," "),"", $area);
$town = str_replace(array(" "," "),"", $town);
str_replace(array(半角、全角空白)、空、変数)となっており
変数の中の半角、全角空白を空要素と入れ替えます。つまり、空白があった場合に削除します。
##エラーメッセージ
if(empty($post_num) === true &&
($area === '都道府県を選択' || empty($city) === true)) {
$error1[] = '郵便番号を入力してください';
}else if ((preg_match('/^[0-9]{7}$/', $post_num) !== 1) &&
($area === '都道府県を選択' || empty($city) === true)) {
$error1[] = '7桁の数字で入力してください';
}else {
print "";
}
areaとcityの入力がしていない場合でないと条件を付けないと
2つの値が入っているときにもエラー文が出てしまう。
}else if ((preg_match('/^[0-9]{7}$/', $post_num) !== 1) &&
($area === '都道府県を選択' || empty($city) === true)) {
$error1[] = '7桁の数字で入力してください';
preg_match(正規表現、文字列)で文字列が正規表現と一致しているかを
確認する
一致していれば1、していなければ0で、失敗するとfalseを返します。
正規表現は0から9までの値を7桁でとなっている。
なので、post_numが7桁の数字出なかった場合、かつareaまたはcityの
値が空だった場合にエラー文が出るようになる。
if ($area === '都道府県を選択' &&
(empty($post_num) === true ||(preg_match('/^[0-9]{7}$/', $post_num) !== 1))) {
$error2[] = '都道府県を選択してください';
}
if(empty($city) === true &&
(empty($post_num) === true ||(preg_match('/^[0-9]{7}$/', $post_num) !== 1))){
$error2[] = '市区町村名をを入力してください';
}
前述とほぼ同じで、post_numに値が入っている場合にはエラー分が出ないようになっています。
##データベースに接続
if(count($error1) === 0 || count($error2) === 0) {
if($link) {
mysqli_set_charset($link, 'utf8');
if($post_num !== '') {
$query = "SELECT post_num, area , city, town FROM pt_table
WHERE post_num = '$post_num'";
エラー文がないときに接続します。文字化けを防止でutf8で表記します。
post_numが空ではない場合にsql文を代入します。
WHERE post_num = '$post_num'";
データベースにある郵便番号の値とpost_numが同じ場合になるのが条件。
} else {
$limit = 10*$page-10;
$query = "SELECT post_num, area , city, town FROM pt_table
WHERE (area = '$area') AND (city = '$city') LIMIT ".$limit.",10";
pageは1番最初のページ数を表しています。 LIMITは開始位置、終わりの位置までを指定。
つまり、10件ごとにページに表示します。
変数limitは0、10、20、30と増えていきます。
$query = "SELECT post_num, area , city, town FROM pt_table
WHERE (area = '$area') AND (city = '$city') LIMIT ".$limit.",10";
データベースのarea,cityの値がそれぞれ一致している場合という条件。
変数limitを”$limit”と書いた場合には文字列となってしまいます。カンマで囲うと数字として扱えます。
##総件数を出すために文字列を取得
$abc = "SELECT post_num, area , city, town FROM pt_table
WHERE (area = '$area') AND (city = '$city')";
$result = mysqli_query($link, $abc);
while($row = mysqli_fetch_array($result)) {
$abc_data[] = $row;
}
}
まず、変数queryでデータを取得しようとすると最大10件しか取得できません。理由はLIMITを使って10件ずつ取得するプログラムになっているからです。なので、別の実行データを
1行ずつ取得し、文字列にしていきます。
##実行したデータを取得
$result = mysqli_query($link, $query);
while($row = mysqli_fetch_array($result)) {
$user_data[] = $row;
}
10件ずつ取得するデータを1行ずつ取得し文字列にします。
##メモリを開放しデータベースから閉じる
mysqli_free_result($result);
mysqli_close($link);
}else {
echo 'DB接続失敗';
}
}
}
##総件数
$count = count($abc_data);
##ページング
<?php if ($page > 1) { ?>
<a href="?page=<?php echo ($page - 1); ?>&area=<?php print $area; ?>
&city=<?php print $city; ?>">前のページへ</a>
<?php } ?>
<?php if ($page < $totalpage) { ?>
<a href="?page=<?php echo ($page + 1); ?>&area=<?php print $area; ?>
&city=<?php print $city; ?>">次のページへ</a>
<?php } ?>
ファイル名?post_num=&area=県名&city=市名とURLに表示させる事を目的にする。
GETで値を取得したときにはURLが表示され、その先頭は?が付きます。
現在のページが1よりも大きいは(page-1)つまり前のページにいきます。
トータルページが今のページよりも多い場合には次のページに行きます
##全コード
<?php
// 変数を設定
$post_num ='';
$area ='';
$city ='';
$town ='';
$error1 = [];
$error2 = [];
$user_data = [];
$abc_data = [];
$query = '';
$host = 'localhost';
$username = 'codecamp31549';
$passwd = 'RXFXXBTL';
$dbname = 'codecamp31549';
$link= mysqli_connect($host, $username, $passwd, $dbname);
$page = 1;
$count = '';//トータル件数
$totalpage = ceil($count/ 10);//切り上げ
/*変数が存在する確認*/
if(isset($_GET['post_num']) === true || isset($_GET['area']) === true) {
if(isset($_GET['post_num']) === true) {
$post_num = $_GET['post_num'];
}
if(isset($_GET['area']) === true) {
$area = $_GET['area'];
}
if(isset($_GET['city']) === true) {
$city = $_GET['city'];
}
if(isset($_GET['town']) === true) {
$town = $_GET['town'];
}
if(isset($_GET['page']) === true) {
$page = $_GET['page'];
}
/*空白削除*/
$post_num = str_replace(array(" "," "),"", $post_num);
$area = str_replace(array(" "," "),"", $area);
$town = str_replace(array(" "," "),"", $town);
/*エラーメッセージ*/
if(empty($post_num) === true &&
($area === '都道府県を選択' || empty($city) === true)) {
$error1[] = '郵便番号を入力してください';
}else if ((preg_match('/^[0-9]{7}$/', $post_num) !== 1) &&
($area === '都道府県を選択' || empty($city) === true)) {
$error1[] = '7桁の数字で入力してください';
}else {
print "";
}
if ($area === '都道府県を選択' &&
(empty($post_num) === true ||(preg_match('/^[0-9]{7}$/', $post_num) !== 1))) {
$error2[] = '都道府県を選択してください';
}
if(empty($city) === true &&
(empty($post_num) === true ||(preg_match('/^[0-9]{7}$/', $post_num) !== 1))){
$error2[] = '市区町村名をを入力してください';
}
/*データベースに接続*/
if(count($error1) === 0 || count($error2) === 0) {
if($link) {
mysqli_set_charset($link, 'utf8');
if($post_num !== '') {
$query = "SELECT post_num, area , city, town FROM pt_table
WHERE post_num = '$post_num'";
// var_dump($query);
} else {
$limit = 10*$page-10;
$query = "SELECT post_num, area , city, town FROM pt_table
WHERE (area = '$area') AND (city = '$city') LIMIT ".$limit.",10";
$abc = "SELECT post_num, area , city, town FROM pt_table
WHERE (area = '$area') AND (city = '$city')";
$result = mysqli_query($link, $abc);
while($row = mysqli_fetch_array($result)) {
$abc_data[] = $row;
}
}
// var_dump($query);
$result = mysqli_query($link, $query);
while($row = mysqli_fetch_array($result)) {
$user_data[] = $row;
}
mysqli_free_result($result);
mysqli_close($link);
}else {
echo 'DB接続失敗';
}
}
}
$count = count($abc_data);
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>郵便</title>
</head>
<body>
<form action="./17-6.php" method="get">
<h1>郵便番号検索</h1>
<h2>郵便番号から検索</h2>
<?php print "総件数" . htmlspecialchars($count,ENT_QUOTES,'UTF-8') . "件";?>
<input type="search" name="post_num" value="">
<input type="submit" value="検索">
<h2>地名から検索</h2>
<label>都道府県を選択
<select name="area">
<option>都道府県を選択</option>
<option>北海道</option>
<option>兵庫県</option>
<option>新潟県</option>
</select>
</label>
<label>市区町村
<input type="seach" name="city">
<input type="submit" value="検索">
</label>
</form>
<p><?php foreach($error1 as $key1 => $string1) {
print htmlspecialchars($string1,ENT_QUOTES,'UTF-8');
}
?></p>
<p><?php foreach($error2 as $key2 => $string2) {
print htmlspecialchars($string2,ENT_QUOTES,'UTF-8');;
}
?></p>
<?php
foreach($user_data as $read) {?>
<table>
<style type="text/css">
table, td, th {
border: solid black 1px;
}
table {
width: 600px;
}
tr td {
width: 150px;
}
</style>
<tr>
<th>郵便番号</th>
<th>都道府県</th>
<th>市町村</th>
<th>町域</th>
</tr>
<tr>
<td><?php print htmlspecialchars($read['post_num'],ENT_QUOTES,'UTF-8'); ?></td>
<td><?php print htmlspecialchars($read['area'],ENT_QUOTES,'UTF-8'); ?></td>
<td><?php print htmlspecialchars($read['city'],ENT_QUOTES,'UTF-8'); ?></td>
<td><?php print htmlspecialchars($read['town'],ENT_QUOTES,'UTF-8'); ?></td>
</tr>
</table>
<?php } ?>
<p>
<!--GETを使用するときは?からスタートする-->
<?php if ($page > 1) : ?>
<a href="?page=<?php echo ($page - 1); ?>&area=<?php print $area; ?>
&city=<?php print $city; ?>">前のページへ</a>
<?php endif; ?>
<?php if ($page < $totalpage) : ?>
<a href="?page=<?php echo ($page + 1); ?>&area=<?php print $area; ?>
&city=<?php print $city; ?>">次のページへ</a>
<?php endif; ?>
</p>
</body>
</html>
```php