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

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

ただいまの
回答率

90.84%

  • PHP

    18688questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • ページネーション

    28questions

    Webアプリケーションにおいて、1ページに収まらないコンテンツを、各ページへのリンクを並べてアクセスしやすくする手法をページネーションと呼びます。

PHP ページネーション 10件づつ表示

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 237

tomochan

score 5

 制作しているシステム

郵便番号や、地名検索から
データベースに管理している
地名を検査して表示させるというシステム。

イメージ説明

 前提・実現したいこと

GETで受け取ったデータの件数を、
10件ずつ表示させるページング機能を実装させたいです。

 行き詰っていること

〇現在ページをどのように定義したら良いかわかわからない
〇if文の条件分岐の書き方がわかりらない
➡・データ件数が10件を超えたときに、「次へ」を表示
➡・2ページ目以降
・「前へ」を表示
・10件を超えたとき、「次へ」を表示
・総ページ数になったら「前へ」だけ表示  
〇URL指定の仕方に自信がない

 試したこと

データ件数、総ページ数、「前へ」のURL、「次へ」のURLを変数で定義しました。

 該当のソースコード

<?php
function h($str){
    return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}



$post_number = '';
$post_number_1 = '';
$address = '';
$message = NULL;
$error = NULL;
$insertOk = true;
$address_data = array();
$query = NULL;
$pref = '';


//郵便番号から検索されたとき
if (isset($_GET['search_1']) === TRUE) {
    $insertOk = true;
    //入力値を変数に代入
    $post_number = $_GET['zipcode'];
    $post_number_1 = str_replace(array(" ", " "), "", $post_number);
    //空の場合のエラー
    //形式チェック
    if (mb_strlen($post_number_1) === 0) {
        $message = '郵便番号を入力してください。';
        $insertOk = false;
    } else if (preg_match('/^[0-9]{7}$/', $post_number_1) !== 1) {
        $message = '郵便番号は7桁の半角数字を入力してください。';
        $insertOk = false;
    }


    if ($insertOk === true) {
       //DBと接続 
        $host =  // データベースのホスト名又はIPアドレス
        $username =  // MySQLのユーザ名
        $passwd   =     // MySQLのパスワード
        $dbname   =     // データベース名
        $link = mysqli_connect($host, $username, $passwd, $dbname);
        if ($link) {
            mysqli_set_charset($link, 'utf8');

            if (isset($_GET['search_1']) === TRUE) { 
                $query = "SELECT * FROM address_table WHERE post_number = '$post_number_1'" ;
            }    
                $result = mysqli_query($link, $query);
                while ($row = mysqli_fetch_array($result)) {
                $address_data[] = $row;
                }

                mysqli_free_result($result);
                mysqli_close($link);
                } else {
                print 'DB接続失敗';
            }

        }
}        
//地名から検索されたとき       
if (isset($_GET["search_2"]) === TRUE) {
    $pref = $_GET["pref"];
    $address = $_GET["address"];
    $insertOk = true;
    if ($pref == NULL) {
        $error = '都道府県を選択してください';
        $insertOk = false;
    } else if ($pref !== NULL && mb_strlen($address) === 0) {
        $error = '市区町村を入力してください。';
        $insertOk = false;
    }

    if ($insertOk === true) {
       //DBと接続 
        $host = 'localhost'; // データベースのホスト名又はIPアドレス
        $username = 'codecamp21605';  // MySQLのユーザ名
        $passwd   = 'MQSOCCZP';    // MySQLのパスワード
        $dbname   = 'codecamp21605';    // データベース名
        $link = mysqli_connect($host, $username, $passwd, $dbname);
        if ($link) {
            mysqli_set_charset($link, 'utf8');

            if (isset($_GET['search_2']) === TRUE) { 
                $query = "SELECT * FROM address_table WHERE city_kanji LIKE '%$address%'" ;
            }    
                $result = mysqli_query($link, $query);
                while ($row = mysqli_fetch_array($result)) {
                $address_data[] = $row;
                }

                mysqli_free_result($result);
                mysqli_close($link);
                } else {
                print 'DB接続失敗';
            }

        }
}
//検索結果が10件以上の時ページネーション

//件数
$address_data_count = count($address_data);
//総ページ数
$pagination = ceil($address_data_count / 10);
//表示件数
$view = 10;
//現在ページ
$page = 1;



$url_back = '?pref=' . $pref . '&address=' . $address . '&search_method=' . 'address&search_2=' . ($page - 1);
$url_next = '?pref=' . $pref . '&address=' . $address . '&search_method=' . 'address&search_2=' . ($page + 1);

?>

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>郵便番号検索</title>
    <style type>
        .search_reslut {
            border-top: solid 1px;
            margin-top: 10px;
        }

        table {
            border-collapse: collapse;
        }
        table, tr, th, td {
            border: solid 1px;
        }
        caption {
            text-align: left;
        }

    </style>
</head>
<body>
    <h1>郵便番号検索</h1>
    <section>
        <h2>郵便番号から検索</h2>
        <form method="get">
            <input type="text" name="zipcode" placeholder="例)1010001" value="">
            <input type="hidden" name="search_method" value="zipcode">
            <input type="submit" name="search_1" value="検索">
        </form>
        <h2>地名から検索</h2>
        <form method="get">
            都道府県を選択
            <select name="pref">
                <option value="" selected>都道府県を選択</option>
                <option value="北海道" >北海道</option>
                <option value="青森県" >青森県</option>
                <option value="岩手県" >岩手県</option>
                <option value="宮城県" >宮城県</option>
                <option value="秋田県" >秋田県</option>
                <option value="山形県" >山形県</option>
                <option value="福島県" >福島県</option>
                <option value="茨城県" >茨城県</option>
                <option value="栃木県" >栃木県</option>
                <option value="群馬県" >群馬県</option>
                <option value="埼玉県" >埼玉県</option>
                <option value="千葉県" >千葉県</option>
                <option value="東京都" >東京都</option>
                <option value="神奈川県" >神奈川県</option>
                <option value="新潟県" >新潟県</option>
                <option value="富山県" >富山県</option>
                <option value="石川県" >石川県</option>
                <option value="福井県" >福井県</option>
                <option value="山梨県" >山梨県</option>
                <option value="長野県" >長野県</option>
                <option value="岐阜県" >岐阜県</option>
                <option value="静岡県" >静岡県</option>
                <option value="愛知県" >愛知県</option>
                <option value="三重県" >三重県</option>
                <option value="滋賀県" >滋賀県</option>
                <option value="京都府" >京都府</option>
                <option value="大阪府" >大阪府</option>
                <option value="兵庫県" >兵庫県</option>
                <option value="奈良県" >奈良県</option>
                <option value="和歌山県" >和歌山県</option>
                <option value="鳥取県" >鳥取県</option>
                <option value="島根県" >島根県</option>
                <option value="岡山県" >岡山県</option>
                <option value="広島県" >広島県</option>
                <option value="山口県" >山口県</option>
                <option value="徳島県" >徳島県</option>
                <option value="香川県" >香川県</option>
                <option value="愛媛県" >愛媛県</option>
                <option value="高知県" >高知県</option>
                <option value="福岡県" >福岡県</option>
                <option value="佐賀県" >佐賀県</option>
                <option value="長崎県" >長崎県</option>
                <option value="熊本県" >熊本県</option>
                <option value="大分県" >大分県</option>
                <option value="宮崎県" >宮崎県</option>
                <option value="鹿児島県" >鹿児島県</option>
                <option value="沖縄県" >沖縄県</option>
            </select>
            市区町村
            <input type="text" name="address" value="">
            <input type="hidden" name="search_method" value="address">
            <input type="submit" name="search_2" value="検索">
        </form>
    </section>
    <section class="search_reslut">

    </section>
<?php if (count($address_data) > 0) { ?>
    <?php print '検索件数' . $address_data_count . '件' . '<br>' . '<br>' . '郵便番号検索結果'; ?>

    <table>

       <tr>
           <th>郵便番号</th>
           <th>都道府県</th>
           <th>市区町村</th>
           <th>町域</th>
       </tr>

     <?php
    foreach ($address_data as $value) {
    ?> 
        <tr>           
            <td><?php print h($value['post_number']); ?></td>
            <td><?php print h($value['pref_kanji']); ?></td>
            <td><?php print h($value['city_kanji']); ?></td>
            <td><?php print h($value['town_kanji']); ?></td>
        </tr>
    <?php    
    }
    ?>

    </table>
<?php    } else { ?>
    <p>ここに検索結果が表示されます</p>
    <?php } ?>

    <?php if ($post_number !== NULL) { ?>
        <?php print $message . "<br>"; ?>
    <?php } ?>  

    <?php if ($address !== NULL) { ?>
        <?php print $error . "<br>"; ?>
    <?php } ?> 

    <!--検索結果が10件以上の時、遷移できるurlを表示-->
    <?php if ($address_data_count > 10) : ?>
    <a href= '<?php print $url_back; ?>'> 前のページへ</a> 
    <?php endif; ?>

    <?php if ($address_data_count > 10) : ?>
    <a href='<?php print $url_next; ?>'>次のページへ</a>
    <?php endif;  ?>


</body>
</html>

 最後に

ページング機能を実装できれば
一通り完成となるので、
分かる方がいらっしゃいましたら、
お力をお貸しください。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • mts10806

    2018/04/20 09:23

    ローカル環境かもしれませんが、ユーザとパスワードはマスク掛けといた方が良いです。

    キャンセル

  • tomochan

    2018/04/20 09:27

    そうですね💦ご指摘いただきありがとうございます!

    キャンセル

回答 2

checkベストアンサー

+2

概念的な話です。ほぼ作り直しになるかもしれません。

検索を POSTに、ページングをGETにすると良いです。
POSTされた検索条件はセッションに入れておき、必ずセッションを参照する。

あとできれば郵便番号とそれ以外はform分けない方がいいかもしれませんね。
郵便番号もあいまい検索した方が検索の仕方としては幅広くなります。

ページングは「全体の総数」「1ページの表示件数」「今何ページ目か」があれば実現可能です。
それぞれを取得するように作ってください。

何ページになるかの計算

切り上げ(総件数 / 1ページ表示数)

1件目が何レコード目かの計算
※この計算結果はSQLで limitかけると良い

(何ページ目-1) * 1ページ表示件数
※SQLの場合01レコード目です

あとは何ページになるかわかればその分forで回してhtmlを作成
?page={$i}
のような形でURLに埋め込み、SQLには$_GET["page"]を利用してlimit かける。

追記:
「総件数」をとってきたあとの変数のcount()でとってきていますが、これはよろしくないです。
というのは住所録となると何万件もの件数となるため、「全部とってきてそこからちょっと取り出す」のは
処理がかなり重たくなり、表示も遅くなります。
SQLでlimitをかけていない状態でcountして総件数とすべきかと思います。

余談:
SQLにユーザーからの入力値を含めるのであれば必ずエスケープをすべきです。

それかPDOでのDBアクセスをご検討ください。
とても参考になる記事:PHPでデータベースに接続するときのまとめ

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/20 09:51

    ご丁寧な説明をしていただきありがとうございます!
    この検索機能の使用は、とある課題のサンプルと一緒のものです。
    また、検索するものは、
    本来ならば日本全国ですが
    データベースの関係上ある一県だけのデータを
    取得してもよいことになっておりました。
    ご教授していただいたものを参考にページネーションを
    実装させます!ありがとうございました!

    キャンセル

  • 2018/04/20 09:56 編集

    > データベースの関係上ある一県だけのデータ
    おそらくそうでしょうね。郵政省のデータベース上だと「約12万件ある」とされています。
    何かしら条件がないと一気に取得するのは難しいですね。
    例えば都道府県は入力必須にするとか。

    「前へ」「次へ」だけで1ページ10件だと中々欲しいデータまで辿りつけないので、
    指定のページ前後5件は出すようにしておくとか、「最初へ」「最後へ」を付け加えたり、
    基本部分が理解できれば幾らでも対応可能となります。

    ページネーション実装にはよく使われる課題だと思うので、
    しっかり作りこんで身につけてください。

    キャンセル

+1

現在のページを1ページ目から始めて$pageだとすれば次のページは$page+1

これをLIMIT句にあてはめ

SELECT * FROM tbl WHRE ・・・ LIMIT ($page-1)*10,10

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

同じタグがついた質問を見る

  • PHP

    18688questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • ページネーション

    28questions

    Webアプリケーションにおいて、1ページに収まらないコンテンツを、各ページへのリンクを並べてアクセスしやすくする手法をページネーションと呼びます。