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

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

新規登録して質問してみよう
ただいま回答率
85.49%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

Q&A

解決済

5回答

6397閲覧

PHP、MYSQLでのページングで次ページがあるかの判別

shabo

総合スコア24

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

0グッド

1クリップ

投稿2017/01/12 06:55

編集2017/01/12 08:29

PHPとMySQLで掲示板を作っています。
ページングの処理で分からないことがあるので質問をさせていただきます。

画面に10件のレコードを表示するようにしています。
データベースにさらに10件以上のデータがあれば次の10件のレコードを表示する「次へ」リンク
なければリンクを表示しない判別をしたいのですが上手くいきません。

ホームページを参考にし、

if(count($row) > $limit){
array_pop($row);
echo '<a href="index.php?p=', $next_num, '">次へ</a>','</td>';
} else {
echo '末尾';
}

で分岐をしたいのですが、$rowのcountがechoで出力したところ1となってしまい上手くいきません。
何か原因があるのでしょうか。もしくは別の方法で分岐を取り入れることは可能でしょうか。

<?php $p = isset($_GET['p']) ? intval($_GET['p']) : 0; $limit = 10; $v_page = $limit + 1; $offset = $p * $limit; $pdo=new PDO('mysql:host=ホスト名;dbname=board;charset=utf8','ユーザー','パス'); $sql=$pdo->prepare('select * from board1 order by nomber desc limit :limit offset :offset '); $sql->bindValue(":limit", $v_page, PDO::PARAM_INT); $sql->bindValue(":offset", $offset, PDO::PARAM_INT); $sql->execute(); while ($row = $sql -> fetch(PDO::FETCH_ASSOC)){ echo '<tr>'; echo '<td>', htmlspecialchars($row['nomber']), '</td>'; echo '<td>', htmlspecialchars($row['name']),'</td>'; echo '<td>', '<img src="',$row['icon'],'.png">','</td>'; echo '<td>', htmlspecialchars($row['trip']), '</td>'; echo '<td>', htmlspecialchars($row['message']), '</td>'; echo '<td>', '<a href="delete-in.php?nomber=', $row['nomber'], '">削除</a>','</td>'; echo '</tr>'; echo "\n"; } $next_num = $p+1; $prev_num = $p-1; if(count($row) > $limit){ array_pop($row); echo '<a href="index.php?p=', $next_num, '">次へ</a>','</td>'; } else { echo '末尾'; } if($p > 0){ echo '<a href="index.php?p=', $prev_num, '">前へ</a>','</td>'; } else { echo ''; }

皆様のご回答を参考に下記で解決いたしました。
・総ページ数を求めるということ、またその求め方
・fetchを使う場合のcountの戻り値
を知ることができ大いに勉強になりました。
ご回答いただきました皆様本当にありがとうございます。

<?php $p = isset($_GET['p']) ? intval($_GET['p']) : 0; $limit = 10; $v_page = $limit + 1; $offset = $p * $limit; $pdo=new PDO('mysql:host=ホスト;dbname=board;charset=utf8','ユーザー','パス'); $sql=$pdo->prepare('select * from board1 order by nomber desc limit :limit offset :offset '); $sql->bindValue(":limit", $v_page, PDO::PARAM_INT); $sql->bindValue(":offset", $offset, PDO::PARAM_INT); $sql->execute(); while ($row = $sql -> fetch(PDO::FETCH_ASSOC)){ echo '<tr>'; echo '<td>', htmlspecialchars($row['nomber']), '</td>'; echo '<td>', htmlspecialchars($row['name']),'</td>'; echo '<td>', '<img src="',$row['icon'],'.png">','</td>'; echo '<td>', htmlspecialchars($row['trip']), '</td>'; echo '<td>', htmlspecialchars($row['message']), '</td>'; echo '<td>', '<a href="delete-in.php?nomber=', $row['nomber'], '">削除</a>','</td>'; echo '</tr>'; echo "\n"; } #ここまでは質問時のソースと同じです。 #ここからソースを書き換えました。 $pdo=new PDO('mysql:host=ホスト;dbname=board;charset=utf8','ユーザー','パス'); $sql=$pdo->query('select * from board1'); $total_res=$sql->rowCount(); $next_num = $p+1; $prev_num = $p-1; $total_page= ceil($total_res / $limit); if($p > 0){ echo '<a href="index.php?p=', $prev_num, '">前へ</a>','</td>'; } else { echo '最新'; } if($total_page-1 > $p){ echo '<a href="index.php?p=', $next_num, '">次へ</a>','</td>'; } else { echo '末尾'; } ?>

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

ベストアンサー

sql

1SELECT * FROM table WHERE column = ? LIMIT 10 offset 0;

これで返ってくるレコード数は最大で10件ですね。1ページあたり10件($count_per_page)ずつ表示する場合、こうなります。

sql

1SELECT COUNT(*) as cnt FROM table WHERE column = ?;

こうすると、同じ検索条件のときの、全件のレコード数($total_count)を取得できます。

レコード数が、128件あったとき、10件ずつ表示すると、

0 〜 9 → 1ページ目
10 〜 19 → 2ページ目
20 〜 29 → 3ページ目
...
120 〜 128 → 13ページ目

となりますね。このとき、13という値($total_page)がわかれば、「次へ」のボタンを表示するかどうかは判定できますので、これを計算で求めることはできますね。

php

1<?php 2$total_count / $count_per_page; // 12.8 3ceil($total_count / $count_per_page); // 13

投稿2017/01/12 07:12

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shabo

2017/01/12 07:36

トータルページの求め方を分かりやすくお教えいただきありがとうございます。 恥ずかしながら小数点を切り捨てるceilという関数を初めて知りました。 実践してみます。
shabo

2017/01/12 07:37

ceilは切り上げるでした。失礼しました。
guest

0

リミットが10件のところわざと1件余計に取得して、その1件があれば「次へ」を表示する仕組みでしょうか。
count($row)では1行ごとに対しての件数になってしまうので、
PDOStatement::rowCount が使えないでしょうか(未検証)

PHP

1if($sql->rowCount() > $limit){

投稿2017/01/12 07:11

ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shabo

2017/01/12 07:19

ご回答ありがとうございます。 はい、仰る通り、1件余分に取得し、余分1件があれば次へが表示される仕組みです。 count($row)は1行分しか数えていないので1だったんですね。 ご提示いただいたPDOStatement::rowCountを試してみます。
KiyoshiMotoki

2017/01/12 08:06

横から失礼します。 SELECT文で取得できた行数を知る目的では、PDOStatement::rowCount は使わない方が良いです。 PHP のマニュアルに、以下のように説明されているからです。 http://php.net/manual/ja/pdostatement.rowcount.php > PDOStatement::rowCount() は 相当する PDOStatement オブジェクトによって実行された 直近の DELETE, INSERT, UPDATE 文によって作用した行数を返します。 > 関連する PDOStatement によって実行された直近の SQL ステートメントが SELECT 文の場合、いくつかのデータベースは文によって返された 行数を返すかも知れません。しかしながら、 この振る舞いは全てのデータベースで保証されていません。 代わりに 「while ($row = $sql -> fetch(PDO::FETCH_ASSOC)) 部分で、  11回以内の $sql -> fetch の実行で false が返却されたら"次のページ"は存在しない」 と、判定する方法をお勧めします。
shabo

2017/01/12 08:18

KiyoshiMotoki 様 補足ありがとうございます。 思ったとおりに動かない可能性があるということですね。 質問本文にはrowCountを使用した追記をしましたが、推奨いただいた方法でも 試してみたいと思います。
guest

0

11件目があれば、11件目から読み直したいということでしょうか。

$resultCount = 0; while ($row = $sql -> fetch(PDO::FETCH_ASSOC)){ $resultCount ++ ; ... } if($resultCount > $limit){ echo '<a href="index.php?p=', $next_num, '">次へ</a>','</td>'; }

投稿2017/01/12 07:32

namimon

総合スコア726

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

namimon

2017/01/12 07:38

rowCount()を忘れてました。削除依頼しています。
shabo

2017/01/12 07:41

ご回答ありがとうございます。 fetchを使う場合はwhileで数値を1ずつ増やしていき、それをcountするということですね。 取得されたものを数えることにしか頭がいかずその考え方は思いつきませんでした。
guest

0

fetch は1レコードしか取得しないと思いますよ
fetchAll を用いて全体の件数を把握してLimit と offset を設定しないと無理だと思います。

投稿2017/01/12 07:14

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shabo

2017/01/12 07:39

fetchを使用していたので$rowのcountの戻り値が1だったんですね。 原因が分かり頭の中が整理できました。
guest

0

あらかじめ全体のページ数とカレントページが何ページ目かを把握しておき

  • カレントページが2ページ目以降なら「前へ」
  • カレントページが最終頁(全体ページ数)より前なら「次へ」

を表示してください
専用のis_firstpage()とかis_lastpage()などの関数をつくってもよいかもしれません

投稿2017/01/12 07:04

yambejp

総合スコア114747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shabo

2017/01/12 07:17

ご回答ありがとうございます。全体のページを取得するというのは思いつきませんでした。 一度試してみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問