質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.22%

PHP 郵便番号検索サイト ページング処理について

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 1,365

gorira6

score 10

前提・実現したいこと

phpで郵便番号検索サイトを作成しています。

以下が要件です
1.郵便番号及び住所の情報をデータベースで管理する。
2.郵便番号から住所が検索できる。
3.検索結果は一覧で「郵便番号、住所」の最低限2つを1行ずつ表示する。
4.郵便番号が未入力だった場合、エラーメッセージを表示する。
5.郵便番号は7桁の数値のみ検索可能とし、それ以外はエラーメッセージを表示する。
6.都道府県と市区町村から住所が検索できる。
7.都道府県、市区町村のどちらか又は両方が未入力だった場合、エラーメッセージを表示する。※どちらか片方だけの検索禁止
8.郵便番号、都道府県、市区町村の入力の前後にある全角及び半角スペースを削除する。入力値チェックや検索はこの後に行う。
例)「 1100001 」→「1100001」
9.検索結果が10件を超えた場合、表示結果を複数ページに分ける。 ※「前へ」「次へ」のようなリンクによりページ切り替えができる

発生している問題・エラーメッセージ

9の要件を実現しようとした際に、データの取得で失敗してしまいエラーが出てしまいます。
おそらく、以下に記述しましたソースコードにて「データベースの処理実行」とコメントアウトしている箇所
のSQL文のLIMIT以降の文章が誤っている為だとは思いますが、なぜ誤りなのかが分かりません。

エラーメッセージ
①Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in /home/codecamp_17142/htdocs/practice_post_code_advanced.php on line 96 
②Warning: mysqli_free_result() expects parameter 1 to be mysqli_result, boolean given in /home/codecamp_17142/htdocs/practice_post_code_advanced.php on line 99 

該当のソースコード

<?php
$message = 'ここに検索結果が表示されます';
$error = '';
$research_result = '';
$post_code = '';
$prefectures = '';
$municipality = '';
$query = '';
$pre_data = array();
$post_data = array();
$search_method = '';
$page_limit = 1;
$page_num = 1;

//都道府県データ
$host = 'localhost';
$username = 'codecamp17142';
$passwd = 'jv652011';
$dbname = 'codecamp17142';
$link = mysqli_connect($host, $username, $passwd, $dbname);
if (isset($_POST['search_method']) === TRUE){
    $search_method = $_POST['search_method'];

}else if(isset($_GET['search_method']) === TRUE){
    $search_method = $_GET['search_method'];

}

if ($link){
    mysqli_set_charset($link, 'utf8');
    $query = 'SELECT prefectures_name FROM pre_table';
    $result = mysqli_query($link, $query);
        while($row = mysqli_fetch_array($result)){
                $pre_data[] = $row;
        }
    mysqli_free_result($result);
}

$request_method = $_SERVER['REQUEST_METHOD'];

if(isset($_GET['search_method']) === TRUE || isset($_POST['search_method']) === TRUE){
    if(isset($_GET['search_method']) === TRUE){
        if($_GET['search_method'] === 'post_search'){
            $post_code = $_GET['post_num'];
        }
        if($_GET['search_method'] === 'area_search'){
            $prefectures = $_GET['pref'];
            $municipality = $_GET['munici'];
        }
    }

    if (isset($_POST['post_code']) === TRUE){
        $post_code = $_POST['post_code'];
        $post_code = trim($post_code);
        if (mb_strlen($post_code) === 0){
            $error = '郵便番号を入力してください。';
        }else if (preg_match('/\d{7}/', $post_code) !== 1){
            $error = '郵便番号は7桁の半角数字を入力してください';
        }
    }

    if (isset($_POST['prefectures']) === TRUE){
        if (($_POST['prefectures']) !== '都道府県を選択'){
            $prefectures = $_POST['prefectures'];
        } else {
            $error = '都道府県を選択してください。';
        }
    }

    if (isset($_POST['municipality']) === TRUE){
        $municipality = $_POST['municipality'];
        $municipality = trim($municipality);
        if (mb_strlen($municipality) === 0){
            $error = '市区町村を入力してください。';
        }
    }

    //データベースの処理実行
    mysqli_set_charset($link, 'utf8');
    $sql_count = '';
   if ($search_method === 'post_search'){
        $query = 'SELECT post_code, prefectures, municipality, area FROM post_table WHERE post_code LIKE \''.$post_code.'\' LIMIT 10 OFFSET'.((($page_num)-1)*10);
        $sql_count = 'SELECT count(post_code) FROM post_table WHERE post_code LIKE \''.$post_code.'\'';
    }else if ($search_method === 'area_search'){
        $query = 'SELECT post_code, prefectures, municipality, area FROM post_table WHERE (prefectures = \''.$prefectures.'\')
        AND (concat(municipality,area) LIKE \'%'.$municipality.'%\') LIMIT 10 OFFSET'.((($page_num)-1)*10);
        $sql_count = 'SELECT count(post_code) FROM post_table WHERE (prefectures = \''.$prefectures.'\')
        AND (concat(municipality,area) LIKE \'%'.$municipality.'%\')';
    }
    //データ件数の取得処理
    $result_count = mysqli_query($link, $sql_count);
    $count_row = mysqli_fetch_row($result_count);
    $page_limit = ceil($count_row[0]/10);
    /*データの取得処理*/
    $result = mysqli_query($link, $query);
    while($row = mysqli_fetch_array($result)){
        $post_data[] = $row;
    }
    mysqli_free_result($result);
    mysqli_close($link);

    if (isset($count_row[0])){
        $message = '検索結果'.  $count_row[0] .'件';
    }

}

?>
<!DOCTYPE html>
<html lang = "ja">
    <head>
        <meta charset="UTF-8">
        <title>郵便番号検索</title>
        <style type="text/css">
        section{
            border-top:solid 1px;
            margin-top:10px;
        }
        table, tr, td, th{
            border: solid black 1px;
        }
        table{
            width:250px;
            border-collapse:collapse;
        }
        caption{
            text-align:left;
        }
        </style>
    </head>
    <body>
        <h1>郵便番号検索</h1>
        <h2>郵便番号から検索</h2>
        <form method="POST">
            <input type="text" name="post_code" value="<?php if (isset($post_code) === TRUE){print $post_code;}?>">
            <input type="hidden" name="search_method" value="post_search">
            <input type="submit" value="検索">
        </form>
        <h2>地名から検索</h2>
        <form method="POST">
            都道府県を選択
            <select name="prefectures">
<?php
foreach ($pre_data as $value){
?>
                <option value = "<?php print $value[0];?>" <?php if($prefectures === $value[0]){print 'selected';}?>><?php print $value[0];?></option>
<?php
}
?>

            </select>
            市区町村
            <input type="text" name="municipality" value = "<?php if (isset($municipality)=== TRUE){print $municipality;}?>">
            <input type="hidden" name="search_method" value="area_search">
            <input type="submit" value="検索">
        </form>
<section>
<p><?php print $message; ?></p>
<p><?php print $error; ?></p>
</section>

        <table>
<?php
if ((mb_strlen($post_code) === 7) || (($prefectures !== '') && (mb_strlen($municipality) > 0))){
?>
<caption>郵便番号検索結果</caption>
            <tr>
                <th>郵便番号</th>
                <th>都道府県</th>
                <th>市区町村</th>
                <th>町域</th>
            </tr>
<?php
}
?>
<?php
foreach ($post_data as $value){
?>
            <tr>
                <td><?php print htmlspecialchars($value['post_code'], ENT_QUOTES, 'UTF-8')?></td>
                <td><?php print htmlspecialchars($value['prefectures'], ENT_QUOTES, 'UTF-8')?></td>
                <td><?php print htmlspecialchars($value['municipality'], ENT_QUOTES, 'UTF-8')?></td>
                <td><?php print htmlspecialchars($value['area'], ENT_QUOTES, 'UTF-8')?></td>
            </tr>
<?php
}
?>
        </table>
<?php   if ($page_num !== 1){ ?>
        <a href = 'practice_post_code_advanced.php?pref=<?php print $prefectures;?>&munici=<?php print $municipality;?>&post_num=<?php print $post_code;?>&search_method=<?php print $search_method;?>&page=<?php print $page_num - 1;?>'>前のページ</a>
<?php   } ?>
<?php   if ($page_num !== $page_limit){ ?>
        <a href = 'practice_post_code_advanced.php?pref=<?php print $prefectures;?>&munici=<?php print $municipality;?>&post_num=<?php print $post_code;?>&search_method=<?php print $search_method;?>&page=<?php print $page_num + 1;?>'>次のページ</a>
<?php   } ?>
    </body>
</html>

試したこと

mysqli_fetch_array() に正しい値が返っていないとのエラーなので
SQL文を何度か書き換えてみました。
まず、LIMIT 10 までは正しいか確かめるために、OFFSET以降は消して実行してみたところ、問題なく処理されました。
では、OFFSET以降がおかしいのだと思い

WHERE post_code LIKE \''.$post_code.'\' LIMIT 10 OFFSET'.((($page_num)-1)*10);


↓↓

WHERE post_code LIKE \''.$post_code.'\' LIMIT 10 OFFSET ((('.$page_num.')-1)*10)';


のように書いてみましたが、相変わらずエラーメッセージは変わらないままでした。

エラーの原因になっている場所と、解決方法について

大変お手数かと思いますが、ご教授して頂けると幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

OFFSETの後にスペース入れたらどうでしょう

WHERE post_code LIKE \''.$post_code.'\' LIMIT 10 OFFSET '.((($page_num)-1)*10);

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/12 16:47

    ありがとうございます!
    無事エラーが消えました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.22%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる