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

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

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

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

PHP

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

3回答

2425閲覧

ページングが上手くいきません(php mysql)

java.empress

総合スコア16

MySQL

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

PHP

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

1クリップ

投稿2016/04/13 02:39

いつもありがとうございます。
今回もご教授頂ければ幸いです。

●実装したい機能
MYSQLからデータを取得してページング処理をしたい。
●困っている点
MYSQLからあるテーブルのデータを全件取得し、一覧の表示は出来るのですが
3件ずつのページングが上手くいきません。

具体的に言いますと
1ページ目の3件は上手く表示されますが、
2ページ目以降も1ページ目と同じデータが3件ずつ表示されてしまいます。

以下コードです。

phoコード

<?php try { $dsn='mysql:dbname=netshop;host=localhost'; $user='root'; $password=''; $dbh=new PDO($dsn,$user,$password); $dbh->query('SET NAMES utf8'); $sql='SELECT pro_code,pro_id,pro_name,pro_subname,pro_koumoku,pro_tanka,pro_kosuto,bikou1,bikou2,gazou FROM mst_product ORDER BY pro_code DESC'; $stmt=$dbh->prepare($sql); $stmt->execute(); $count=$stmt->rowCount(); $dbh=null; $max = 3; //1ページあたりの表示数 $limit = ceil($count/$max); //最大ページ数 $page = empty($_GET["page"])?(int)1:(int)$_GET["page"]; //ページ番号 $start = ($page ==1)?0: ($page-1) * $max; $end = ($page * $max); // var_dump($start); // var_dump($end); /* 確認用 print "<p>"; print "count:".$count."<br>"; print "max:".$max."<br>"; print "start:".$start."<br>"; print "end:".$end."</p>"; */ for($i=$start;$i<$end;$i++) { $rec=$stmt->fetch(PDO::FETCH_ASSOC); print '<a href="itemsyousai.php?procode='.$rec['pro_code'].'"><img src="../product/gazou/'.$rec['gazou'].'" width="170" height="150" alt='.$rec['pro_name'].'<br />'; print '</a>'; print '<a href="itemsyousai.php?procode='.$rec['pro_code'].'">'; print ''.$rec['pro_name'].''; print '<br>'; print ''.$rec['pro_subname'].''; print '<br>'; print '商品ID : '.$rec['pro_id'].'<br />'; print '価格 :'.$rec['pro_tanka'].'円'; print '<br>'; print '</a>'; print ''.$rec['bikou1'].''; if($rec==false) { break; } } } catch(Exception $e) { print'ただいま障害により大変ご迷惑をお掛けしております。'; exit(); } include("../include/paging2.php"); paging($limit,$page,3); var_dump($page); ?>

ページングのメソッド

<?php function paging($limit, $page, $disp=3){ //$dispはページ番号の表示数 $next = $page+1; $prev = $page-1; //var_dump($next); //int型で返される //ページ番号リンク用 $start = ($page-floor($disp/2) > 0) ? ($page-floor($disp/2)) : 1;//始点 //floor 小数点以下切り捨て $end = ($start > 1) ? ($page+floor($disp/2)) : $disp;//終点 $start = ($limit < $end)? $start-($end-$limit):$start;//始点再計算 if($page != 1 ) { print '<a href="?page='.$prev.'">&laquo; 前へ</a>'; } //最初のページへのリンク if($start >= floor($disp/2)){ print '<a href="?page=1">1</a>'; if($start > floor($disp/2)) print "..."; //ドットの表示 } for($i=$start; $i <= $end ; $i++){//ページリンク表示ループ $class = ($page == $i) ? ' class="current"':"";//現在地を表すCSSクラス if($i <= $limit && $i > 0 )//1以上最大ページ数以下の場合 print '<a href="?page='.$i.'"'.$class.'>'.$i.'</a>';//ページ番号リンク表示 } //最後のページへのリンク if($limit > $end){ if($limit-1 > $end ) print "..."; //ドットの表示 print '<a href="?page='.$limit.'">'.$limit.'</a>'; } if($page < $limit){ print '<a href="?page='.$next.'">次へ &raquo;</a>'; } /*確認用 print "<p>current:".$page."<br>"; print "next:".$next."<br>"; print "prev:".$prev."<br>"; print "limit:".$limit."<br>"; print "start:".$start."<br>"; print "end:".$end."</p>"; */ } ?>

$rec=$stmt->fetch(PDO::FETCH_ASSOC);の箇所が原因かなと思っているのですが
なかなか上手くいかず困っています。

どうぞよろしくお願いいたします。

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

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

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

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

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

guest

回答3

0

ベストアンサー

ご自身で予想されている通り、

$rec=$stmt->fetch(PDO::FETCH_ASSOC);の箇所

周辺のfor文の書き方が原因です。

php

1for($i=$start;$i<$end;$i++)


「DBから取得したレコードのうち、$start行目以上$end行未満のレコードを表示」
しようとしているつもりかと思いますが、
実際は
「変数$i$startから開始して1ずつ増加させ、$endに達したら終了」
という意味になりますので、必ず最初の3行だけを表示してしまうことになります。

行数が$startに達するまで繰り返し$stmt->fetchを呼び出す必要があるので、
以下のように修正すればうまく行くと思います。

Before

php

1for($i=$start;$i<$end;$i++) 2{ 3$rec=$stmt->fetch(PDO::FETCH_ASSOC); 4 5 6 print '<a href="itemsyousai.php?procode='.$rec['pro_code'].'"><img src="../product/gazou/'.$rec['gazou'].'" width="170" height="150" alt='.$rec['pro_name'].'<br />'; 7 print '</a>'; 8 print '<a href="itemsyousai.php?procode='.$rec['pro_code'].'">'; 9 print ''.$rec['pro_name'].''; 10 print '<br>'; 11 print ''.$rec['pro_subname'].''; 12 print '<br>'; 13 print '商品ID : '.$rec['pro_id'].'<br />'; 14 print '価格 :'.$rec['pro_tanka'].'円'; 15 print '<br>'; 16 print '</a>'; 17 print ''.$rec['bikou1'].''; 18if($rec==false) 19{ 20 break; 21} 22 23 }

After

php

1for ($i=0; $i<$end; $i++) 2{ 3 $rec=$stmt->fetch(PDO::FETCH_ASSOC); 4 if ($rec === false) 5 { 6 break; 7 } 8 9 if ($i < $start) 10 { 11 continue; 12 } 13 14 print '<a href="itemsyousai.php?procode='.$rec['pro_code'].'"><img src="../product/gazou/'.$rec['gazou'].'" width="170" height="150" alt='.$rec['pro_name'].'<br />'; 15 print '</a>'; 16 print '<a href="itemsyousai.php?procode='.$rec['pro_code'].'">'; 17 print ''.$rec['pro_name'].''; 18 print '<br>'; 19 print ''.$rec['pro_subname'].''; 20 print '<br>'; 21 print '商品ID : '.$rec['pro_id'].'<br />'; 22 print '価格 :'.$rec['pro_tanka'].'円'; 23 print '<br>'; 24 print '</a>'; 25 print ''.$rec['bikou1'].''; 26}

ついでに、if($rec==false)$stmt->fetchを呼び出した直後にチェックすべきです。
さもないと、おかしなデータを出力してしまうことになりますので。
http://php.net/manual/ja/pdostatement.fetch.php

投稿2016/04/13 03:49

KiyoshiMotoki

総合スコア4791

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

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

java.empress

2016/04/13 04:52

ご回答ありがとうございます。 頂いた回答で解決する事ができました! if ($i < $start){ continue;} が必要だったんですね。 なるほど。。。 あとif($rec==false)の入力場所も勉強になりました。
guest

0

SQLのSELECT文でLIMIT&OFFSET指定して必要なレコードのみ読みだして、読みだした全レコードを表示する方が適切だと思います。
php側で読み飛ばしをしようちしているようですが、何十万レコード何百万レコードが相手になると処理時間ばかりかかってしまいますから。

参考:MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.2.9 SELECT 構文
http://dev.mysql.com/doc/refman/5.6/ja/select.html

投稿2016/04/13 03:00

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

java.empress

2016/04/13 04:54

ご回答ありがとうございます。 なるべく1回で取り込んだ方がいいのかと思っておりましたが 確かにレコード数が増えた場合、時間が掛かってしまいますね。 勉強になりました!
guest

0

ぱっとみoffsetに関する情報がsqlの文に含まれていないような気がします。

投稿2016/04/13 03:00

realizerS

総合スコア265

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

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

java.empress

2016/04/13 04:56

offsetの方法も確認してみます。 ご回答ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問