• ベストアンサー
  • すぐに回答を!

PDOでDB ページング

  • 質問No.8576132
  • 閲覧数621
  • ありがとう数11
  • 気になる数0
  • 回答数12
  • コメント数0
一覧画面と検索画面を一緒にしています
一覧画面は10件表示にし、テキストになにも入力されてなかったらデータを全件表示したいです
また、1 l 2 l 3 のようにページを表示し、また何件中何件目データですと表示したいです
<!--一覧画面 index.php-->
<html>
<head>
<title>一覧画面</title>
</head>
<body>
<br><br>
<blockquote>
一覧画面
<br><br>
<?php
if ($_GET) { // データがGETされていたら
$event = isset($_GET['event']) ? $_GET['event'] : ''; // 取得
if (isset ($_GET['page'])==false) {
$page=0;
} else {
//そうでなければpageパラメータの値をpage変数にセット
$page = $_GET['page'];
}
}
?>
<?php
$pdo = new PDO("mysql:dbname=db_test;host=localhost", "root", "admin");
$name=isset($_GET['name'])?$_GET['name']:"";
$sql ="select * from tbl_test where ";
$sql.="`氏名` like concat('%',?,'%') ";
$sql.="or `住所` like concat('%',?,'%') ";
$sql.= " limit " . $page*10 . ", 10" ;
$stmt = $pdo->prepare( $sql);
$stmt->execute(array($name,$name));
$count = $stmt->rowCount();
if($count>0){
print "<table border=1>" ;
print "<tr>";
print "<th>番号</th>";
print "<th>氏名</th>";
print "<th>住所</th>";
print "<th>操作</th>";
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
print "</tr>";
$ID = htmlspecialchars($row['番号']);
$NAME = htmlspecialchars($row['氏名']);
$ADDR = htmlspecialchars($row['住所']);
echo "<tr>
<td>$ID</td>
<td>$NAME</td>
<td>$ADDR</td>
<td><a href='edit.php?番号=$ID'>修正</a>
<a href='delete.php?番号=$ID'>削除</a></td></tr>";
};
print "</table>" ;
}else{
print "該当するデータがありません";
}
?>
<br><br><br>
<form action = "index.php" method="GET">
<input type="hidden" name="event" value="find">
<input type="text" name="name"style ="font-size:20px;width: 400px; height: 40px">
<input type="submit" value="検索" style ="font-size:20px;width: 100px; height: 40px">
</form>
<br><br>
<form action = "regist.php" method="GET">
<input type="hidden" name="event" value="regist">
<input type = "submit" value = "新規登録" style ="font-size:20px;width: 100px; height: 40px">
</form>
<input type="hidden" name="page" value="0">
</blockquote>
</body>
</html>
検索のテキストボックスが空だったら全件表示したいのですが今10件しか出ません
limitの書く場所が原因でしょうか?
またこのように一覧画面と検索結果画面が一緒じゃまずいですかね?
検索結果を別ウインドウじゃなく自分に返したいと思いこのやり方にしたのですがよくないですか?

質問者が選んだベストアンサー

  • 回答No.9
  • ベストアンサー

ベストアンサー率 51% (3827/7415)

>(1)がbになってしまいます

ああなるほど、絞り込みをしない場合も全件表示でしたっけ?
で、pageがあるときは絞り込みがない場合だけページング・・・ですか
ようやく見えてきました。

試してみればわかりますが、正直あまりいいUIではありませんね
全件表示してあるところからページングをする意味がないので
(全件表示させないためのページングですから)

とりあえずご指示のとおりであればこんな感じ?

$sql ="select * from tbl_test where 1 ";
if($name!==""){
$sql.="and (0 ";
$sql.="or `氏名` like concat('%',?,'%') ";
$sql.="or `住所` like concat('%',?,'%') ";
$sql.=") ";
}elseif(isset($_GET["page"])){
$sql.= " limit {$page},{$perpage}" ;
}
お礼コメント
noname#197690
ありがとうございます
あとは
15件中 1-10件目 何ページ目表示とやりたいです
PDOで書くにはどうしたらいいですか?
どう<a>タグに反映されるか教えてください
<前 l1l2l次>
投稿日時:2014/05/01 14:51

その他の回答 (全11件)

  • 回答No.12

ベストアンサー率 51% (3827/7415)

>PHPの板に書けば回答くれますか?

ページングの部分に絞って質問をしてもらえれば回答できるかもしれません

ページングで必要なのは
・現在のページ番号
・検索結果のアイテム数
・1ページに表示するアイテム数
・現在ページが最初のページかどうか
・現在ページが最後のページかどうか
あたりです。
このあたりの情報をまとめればさほど難しくない処理でしょう
  • 回答No.11

ベストアンサー率 51% (3827/7415)

>自分のソースに置き換えたらどう書けばいいですか?

だからMySQLの板で回答すべきことではないので回答できません
お礼コメント
noname#197690
PHPの板に書けば回答くれますか?

とりあえず次のページ 前のページに移動できるようにしたいと思います
<?php
$cnt = $row[0] ;

//ページ表示
if(!$cnt > 10) {
echo ceil($cnt / 10), "ページの中の", $page + 1, "ページ目を表示<br>" ;
}
//前の10件
if ($page != 0) {
echo '<a href="index.php?page=' . ($page - 1) . '">前の10件</a>';
}

//次の10件
if (($page + 1)*10 < $cnt) {
echo '<a href="index.php?page=' . ($page + 1) . '">次の10件</a>';
}
?>
これでリンクも何も表示されないのですがなぜですかね?
投稿日時:2014/05/01 16:37
  • 回答No.10

ベストアンサー率 51% (3827/7415)

>15件中 1-10件目 何ページ目表示とやりたいです

必要な情報が3つあります

・ヒットするアイテム数($totalItems)
・現在のページ番号($currentPage・・・$_GET["page"]の値)
・1ページ当たりの表示アイテム数($perPage)

まずは$totalItemsを得ること
select count(*) as totalItems from テーブル where 条件
あたりでいけるでしょう

これをもとに
for($i=0;$i<(int)($totalItems / $perPage);$i++){
print "<a href="hoge.php?page=".$i."&amp;name=".urlencode($name)."\">".($i+1)."</a>";
}
のような処理で、表示一覧を得ます

print $totalItems."件中 ".($currentPage*$perPage+1)."-";
print ($currentPage+1)*$perPage."件目";

のようにして現在のページの情報を表示します
(最大数を件数の上限にしたい場合はもうちょい工夫がいります)

情報としては
select * from テーブル where 条件 limit $currentPage*$perPage,$perPage

から得たデータをテーブル形式に成型して表示します

その他例外処理やらなにやら入れなくちゃいけない処理も多く
ここまでくるとMySQLの板で質問するべきことではないですね。
PHP側でクラスを組んで機能を細分化しながらつくる必要があると思います
お礼コメント
noname#197690
ありがとうございます
やろうとしてることはわかります
自分のソースに置き換えたらどう書けばいいですか?
何度もすいません
投稿日時:2014/05/01 16:28
  • 回答No.8

ベストアンサー率 51% (3827/7415)

ちなみに個人的には絞り込みがあろうが無かろうが「ページングする」というのが
UIとしては正しいと思います。

出現頻度の高い特定のキーワードでヒットするのが何十件となったときに
ユーザビリティがさがるので・・・

また、or検索(xかyでヒットする)やand検索(xかつyのときヒットする)など
実装していくとまた工夫が必要になっていきます
とくにand検索は順列か(x,yで検索したときにx→yの順番でヒットした場合表示)
ランダム(順番にかかわらずx,yがともにヒットしたら表示)かによっても
処理がことなるので実装に注意が必要
お礼コメント
noname#197690
ありがとうございます
そうですね。いまデータが少ないのでいいんですが何十件となったときに大変ですね。
絞り込みがなかろうがあろうが「ページングする処理にしたいです」
とりあえず今ないときのみやり理解してから行いたいと思います

あとは
15件中 1-10件目 何ページ目表示とやりたいです
PDOで書くにはどうしたらいいですか?
どう<a>タグに反映されるか教えてください
<前 l1l2l次>
投稿日時:2014/05/01 14:41
  • 回答No.7

ベストアンサー率 51% (3827/7415)

>(1)はa
>(2)はb
>(3)(4)もa

なるほどねぇ、私の理解がだいぶ違いました
絞り込みをしない場合はページングして
絞り込みをした場合はページングしないということですね

$sql ="select * from tbl_test where 1 ";
if($name!==""){
$sql.="and (0 ";
$sql.="or `氏名` like concat('%',?,'%') ";
$sql.="or `住所` like concat('%',?,'%') ";
$sql.=") ";
}else{
$sql.= " limit {$page},{$perpage}" ;
}

でいけるんじゃないでしょうか?
お礼コメント
noname#197690
はいそういうこうです
けど
(1)がbになってしまいます
<?php
if ($_GET) { // データがGETされていたら
$event = isset($_GET['event']) ? $_GET['event'] : ''; // 取得

}
$pdo = new PDO("mysql:dbname=db_test;host=localhost", "root", "admin");
$name=isset($_GET['name'])?$_GET['name']:"";
$perpage=10;
$page=isset($_GET['page'])?($_GET['page']*$perpage):0;
$sql ="select * from tbl_test where 1 ";
if($name!==""){
$sql.="and (0 ";
$sql.="or `氏名` like concat('%',?,'%') ";
$sql.="or `住所` like concat('%',?,'%') ";
$sql.=") ";
}else{
$sql.= " limit {$page},{$perpage}" ;
}
$stmt = $pdo->prepare( $sql);
$stmt->execute(array($name,$name));
$count = $stmt->rowCount();
if($count>0){
print "<table border=1>" ;
print "<tr>";
print "<th>番号</th>";
print "<th>氏名</th>";
print "<th>住所</th>";
print "<th>操作</th>";
print "</tr>";
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$ID = htmlspecialchars($row['番号']);
$NAME = htmlspecialchars($row['氏名']);
$ADDR = htmlspecialchars($row['住所']);
echo "<tr>
<td>$ID</td>
<td>$NAME</td>
<td>$ADDR</td>
<td><a href='edit.php?番号=$ID'>修正</a>
<a href='delete.php?番号=$ID'>削除</a></td></tr>";
print "</tr>";
};
print "</table>" ;
}else{
print "該当するデータがありません";
}
?>

こんな感じですか?
あとは
15件中 1-10件目 何ページ目表示とやりたいです
PDOで書くにはどうしたらいいですか?
<前 l1l2l次>
投稿日時:2014/05/01 14:27
  • 回答No.6

ベストアンサー率 51% (3827/7415)

場合分けをしましょう

○仮データ
x=11件、y=5件というデータを投入したとして

(1)検索語を指定しないとき
1-a)16件ヒットして全部表示
1-b)16件ヒットして10件ずつ表示
1-c)絞り込みをしない場合はヒットさせない
1-d)そのた?

(2)「x」で絞り込み
2-a)11件ヒットして10件ずつ表示
2-b)11件ヒットして全部表示
2-c)そのた?

(3)「y」で絞り込み
3-a)5件ヒットして全部表示
3-b)そのた?

(4)「z」(存在しないデータ)で絞り込み
4-a)ヒットしないので「ヒットしない」と表示
4-b)ヒットしないので0件表示(テーブルのヘッダ部分はそのまま)
4-c)そのた?

今までの説明をみるとすべてパターンaだと思っていたのですが
#5の補足をみるかぎり1はb?
また(2)についてはページングの際に11件目からデータがとれないということ?
お礼コメント
noname#197690
すいません
少し話を戻させていただきます
これ聞いたらこの人自分のプログラム理解してないのかよって思われると思いますがこの一覧画面の表示の仕方
間違ってますかね?LIKEで表示しているので
LIKEで表示してるからlocalhost/index.phpで開いても検索語がないと見なされるのですか?だから10件表示じゃなく全件表示されてしまうんですかね?

最初検索結果と一覧画面を分けて表示していたのですが一緒にして一覧画面から絞りだされてように検索結果を出しているのですが記述あってますか

(1)はa
(2)はb
(3)(4)もa
です
全件表示を10件でわけページングしたいです

わかりにくくすいません
投稿日時:2014/05/01 14:13
  • 回答No.5

ベストアンサー率 51% (3827/7415)

ごめんなさい、なにか話がかみ合ってない気がしますが

検索文字列になにか文字をいれても絞り込みされずに全件表示されるということでしょうか?
それとも絞りこみはされるけど、10件ごとではなくlimitなしの検索に
なってしまうということでしょうか?

見る限り、nameに文字がはいっていればそれを利用して検索して10件ずつ表示
nameに文字がはいっていない場合は絞り込みをせずに全件表示という仕様で
そのとおり表示されるはずですが

ちなみにソースの前半部の
>if (isset ($_GET['page'])==false) {
>$page=0;
>} else {
>//そうでなければpageパラメータの値をpage変数にセット
>$page = $_GET['page'];
>}

このくだりは、別に記載があるので不要です
お礼コメント
noname#197690
なんて言えばいいんでしょう
一覧画面と検索結果画面がイコール(同phpで実行されている)それでそのページを10件ごとわけて2ページには11件目からのデータ表示

今試しに適当にaというレコードを11件作ってaと入力して検索してた10件のみ表示されました。
そうではなくトップ画面=検索結果画面なんですけど最初検索結果画面を10件表示しl2lを押すと11件目したいに行い検索のテキストが空白で検索ボタンを押すと全件表示したいということです。

説明って難しいですね
言ってる意味がわからなかったらまた言ってください

すいません
お願いします
投稿日時:2014/05/01 13:16
  • 回答No.4

ベストアンサー率 51% (3827/7415)

>消しましたが10件表示ではなく全件表示になっています

ん?nameが空だからじゃないの?
nameが空の場合は全件表示という仕様ですよね?
仕様をもう一度よく練り直した方がよいのでは?
お礼コメント
noname#197690
はい
空だったら全件表示です
いま一覧画面に検索結果を自分に返しているのですが、
最初にlocalhost/index.phpとアドレスバーに入力したら10件表示され検索のテキストボックズが空白だったら全件表示されるということです
日本語が下手でごめんなさい
これやり方違ってますか?
投稿日時:2014/05/01 11:48
  • 回答No.3

ベストアンサー率 51% (3827/7415)

>$sql.= "select count(*) from tbl_test " ;

この行いらないね
お礼コメント
noname#197690
消しましたが10件表示ではなく全件表示になっています
なかなか難しいですね
これってあれですかね
pegeを渡してないからですか?
<input type="hidden" name="page" value="0">
で自分自身に渡してるから大丈夫ですか
$page=0、$perpae=10ってなって1件目から10件目が表示されるはずですよね
<?php
if ($_GET) { // データがGETされていたら
$event = isset($_GET['event']) ? $_GET['event'] : ''; // 取得
if (isset ($_GET['page'])==false) {
$page=0;
} else {
//そうでなければpageパラメータの値をpage変数にセット
$page = $_GET['page'];
}
}
$pdo = new PDO("mysql:dbname=db_test;host=localhost", "root", "admin");
$name=isset($_GET['name'])?$_GET['name']:"";
$perpage=10;
$page=isset($_GET['page'])?($_GET['page']*$perpage):0;
$sql ="select * from tbl_test where 1 ";
if($name!==""){
$sql.="and (0 ";
$sql.="or `氏名` like concat('%',?,'%') ";
$sql.="or `住所` like concat('%',?,'%') ";
$sql.=") ";
$sql.= " limit {$page},{$perpage}" ;
}
$stmt = $pdo->prepare( $sql);
$stmt->execute(array($name,$name));
$count = $stmt->rowCount();
if($count>0){
print "<table border=1>" ;
print "<tr>";
print "<th>番号</th>";
print "<th>氏名</th>";
print "<th>住所</th>";
print "<th>操作</th>";
print "</tr>";
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$ID = htmlspecialchars($row['番号']);
$NAME = htmlspecialchars($row['氏名']);
$ADDR = htmlspecialchars($row['住所']);
echo "<tr>
<td>$ID</td>
<td>$NAME</td>
<td>$ADDR</td>
<td><a href='edit.php?番号=$ID'>修正</a>
<a href='delete.php?番号=$ID'>削除</a></td></tr>";
print "</tr>";
};
print "</table>" ;
}else{
print "該当するデータがありません";
}
?>
投稿日時:2014/05/01 11:29
  • 回答No.2

ベストアンサー率 51% (3827/7415)

よくよく考えたら$nameが空ならwhere句もいらないね

$name=isset($_GET['name'])?$_GET['name']:"";
$perpage=10;
$page=isset($_GET['page'])?($_GET['page']*$perpage):0;
$sql ="select * from tbl_test where 1 ";
if($name!==""){
$sql.="and (0 ";
$sql.="or `氏名` like concat('%',?,'%') ";
$sql.="or `住所` like concat('%',?,'%') ";
$sql.=") ";
$sql.= " limit {$page},{$perpage}" ;
}

のような感じ
ただしこのように?の位置関係が確定できな場合
prepareの関係で$nameを?に代入するのはbindValueにした方がよいかも
現レベルの絞り込みならexcuteに配列をセットするやり方でも
無視されるので問題はありませんが
お礼コメント
noname#197690
いつもありがとうございます

$pdo = new PDO("mysql:dbname=db_test;host=localhost", "root", "admin");
$name=isset($_GET['name'])?$_GET['name']:"";
$perpage=10;
$page=isset($_GET['page'])?($_GET['page']*$perpage):0;
$sql ="select * from tbl_test where 1 ";
if($name!==""){
$sql.="and (0 ";
$sql.="or `氏名` like concat('%',?,'%') ";
$sql.="or `住所` like concat('%',?,'%') ";
$sql.=") ";
$sql.= " limit {$page},{$perpage}" ;
}
$sql.= "select count(*) from tbl_test " ;
$stmt = $pdo->prepare( $sql);
$stmt->execute(array($name,$name));
$count = $stmt->rowCount();
if($count>0){
print "<table border=1>" ;
print "<tr>";
print "<th>番号</th>";
print "<th>氏名</th>";
print "<th>住所</th>";
print "<th>操作</th>";
print "</tr>";
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$ID = htmlspecialchars($row['番号']);
$NAME = htmlspecialchars($row['氏名']);
$ADDR = htmlspecialchars($row['住所']);
echo "<tr>
<td>$ID</td>
<td>$NAME</td>
<td>$ADDR</td>
<td><a href='edit.php?番号=$ID'>修正</a>
<a href='delete.php?番号=$ID'>削除</a></td></tr>";
print "</tr>";
};
print "</table>" ;
}else{
print "該当するデータがありません";
}
これで合ってますか?
該当者なしとしか出ないですね
すいません
投稿日時:2014/05/01 10:44
11件中 1~10件目を表示
結果を報告する
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。
AIエージェント「あい」

こんにちは。AIエージェントの「あい」です。
あなたの悩みに、OKWAVE 3,600万件のQ&Aを分析して最適な回答をご提案します。

関連するQ&A

その他の関連するQ&Aをキーワードで探す

ピックアップ

ページ先頭へ