あなたの習慣について教えてください!!

MySQL、PHP 初心者です。
質問タイトルの通り、MySQL から PHP にデータを読み込む際のページ分けの方法がわかりません。


元の MySQL の内容は次の通りで、データ個数は7個です。
+-----------+---------------+
| book_kind | book_name |
+-----------+---------------+
| ジャンル1 | ジャンル1の本 |
| ジャンル2 | ジャンル2の本 |
| ジャンル3 | ジャンル3の本 |
| ジャンル4 | ジャンル4の本 |
| ジャンル5 | ジャンル5の本 |
| ジャンル6 | ジャンル6の本 |
| ジャンル7 | ジャンル7の本 |
+-----------+---------------+

この7個のデータを1ページに3個ずつ表示させたいのですが、うまくいきません。

実際の表示は次のようになってしまっています。


(1ページ目)
ジャンル1  ジャンル1の本
ジャンル2  ジャンル2の本
ジャンル3  ジャンル3の本
ジャンル4  ジャンル4の本
ジャンル5  ジャンル5の本
ジャンル6  ジャンル6の本
ジャンル7  ジャンル7の本
全件数4件 前へ 1 2 次へ

注)「2」と「次へ」にはリンクが作成されている。



(2ページ目)
ジャンル1  ジャンル1の本
ジャンル2  ジャンル2の本
ジャンル3  ジャンル3の本
ジャンル4  ジャンル4の本
ジャンル5  ジャンル5の本
ジャンル6  ジャンル6の本
ジャンル7  ジャンル7の本
全件数4件 前へ 1 2 次へ

注)「1」と「前へ」にはリンクが作成されている。



7個のデータを1ページに3個ずつ表示させるつもりが
 「1ページ目に7件すべて表示されており、しかも全件数『4件』と表示されている。
 2ページ目にも7件すべて表示されており、しかも全件数『4件』と表示されている」
という状態になっております。

変数の設定に決定的なミスがあると思うのですが、いろいろと試してみたものの、完全に行き詰ってしまいました。
具体的に、間違い箇所を指摘いただければ幸いです。



作成した PHP は次の通りです。


<?php

require_once("data/db_info.php");

$s=new PDO("mysql:host=$SERV;dbname=$DBNM",$USER,$PASS);

print <<<eot1
<!DOCTYPE html>
<html lang="ja">
<html>
<head>
<meta charset="utf-8" />
</head>

<body>
eot1;

$re=$s->query("SELECT * FROM book1");

define('MAX','3'); // 1ページあたりの表示件数

while($kekka=$re->fetch()){
$kekka_num = count($kekka); // トータルデータ件数
$max_page = ceil($kekka_num / MAX); // トータルページ数
if(!isset($_GET['page_id'])){ // $_GET['page_id'] はURLに渡された現在のページ数
$now = 1; // 設定されていない場合は1ページ目にする
}else{
$now = $_GET['page_id'];
}


$start_no = ($now - 1) * MAX; // 配列の何番目から取得すればよいか

$disp_data = array_slice($re, $start_no, MAX, true);
/* array_sliceは、配列の何番目($start_no)から
何番目(MAX)まで切り取る関数 */
print $kekka[0]."  ".$kekka[1]."<br />"; // 抽出データの表示
}


echo '全件数'. $kekka_num. '件'. ' '; // 全データ数の表示

if($now > 1){ // リンクをつけるかの判定
echo '<a href=\'/test_pagination2.php?page_id='.($now - 1).'\')>前へ</a>'. ' ';
} else {
echo '前へ'. ' ';
}

for($i = 1; $i <= $max_page; $i++){ // トータルページ数分、各ページへのリンクを作成
if ($i == $now) { // 現在表示中のページ数の場合はリンクを貼らない
echo $now. ' ';
} else {
echo '<a href=\'/test_pagination2.php?page_id='. $i. '\')>'. $i. '</a>'. ' ';
}
}

if($now < $max_page){ // リンクをつけるかの判定
echo '<a href=\'/test_pagination2.php?page_id='.($now + 1).'\')>次へ</a>'. ' ';
} else {
echo '次へ';
}

?>

</body>
</html>

A 回答 (5件)

あ、1箇所ミスありましたね。

気づいた様ですが。

x $res_array = array_chunk($data,MAX);
o $res_array = array_chunk($res_array,MAX);

で、ページを1スタートにするには↓

// ページ毎に配列を分割
$res_array = array_chunk($data,MAX);
↑の直後に下記を追記。
array_unshift($res_array, "dummy");
unset($res_array[0]);
    • good
    • 0
この回答へのお礼

修正しましたら、うまく動きました。
何度もお付き合いいただき、ありがとうございました。

実は、結構大手のパソコンスクールに通って勉強したのですが、PHPは基礎ぐらいしかカリキュラムに入っていないことに最近になって気づきました。高い授業料を支払っているのでなんでも相談できると思っていたら、カリキュラム以外のことは一切教えてくれない、ということも最近になって知りました。

あわてて「MySQL + PHP」のような本を買ってきて勉強しましたが、いざ動的ホームページを作成しようとすると、ページ分けができないとどうしようもありません。1週間ぐらいページ分けで悩み続けましたが思い切って相談して良かったです。

本当にありがとうございました。

お礼日時:2019/04/02 23:13

> という感じでご回答いただけないでしょうか。



そんな手取り足取りを希望するなら、勉強会行くなりしてください。
どのようなコードにしたらどのような結果になったというのを具体的に書かずに「うまくいきません」というのはダメな質問の典型ですよ。

という説教だけなのはアレなんで、↓このくらいまで書けば理解できますか?
デバッグしてないんで、そこら辺は直してください。

<これ以前は省略>
define('MAX','3'); // 1ページあたりの表示件数

$res_array = array();
$kekka_num = 0;
while($kekka = $re->fetch()){
$res_array[] = $kekka;
// トータルデータ件数
$kekka_num++;
}

// ページ毎に配列を分割
$res_array = array_chunk($data,MAX);
// トータルページ数
$max_page = count($res_array);

if(!isset($_GET['page_id'])){ // $_GET['page_id'] はURLに渡された現在のページ数
$now = 1; // 設定されていない場合は1ページ目にする
}else{
$now = $_GET['page_id'];
}

foreach($res_array[$now] AS $key => $kekka){
print $kekka[0]."  ".$kekka[1]."<br />"; // 抽出データの表示
}

echo '全件数'. $kekka_num. '件'. ' '; // 全データ数の表示

<これ以降は省略>
    • good
    • 0
この回答へのお礼

お忙しいところ何度も申し訳ありません。
修正してみましたが、下記の通りになっています。
ページ番号と中身の表示のずれを修正するには、どうすればよいでしょうか?


(1ページ目) http://localhost/test_pagination7.php?page_id=1

ジャンル4  ジャンル4の本
ジャンル5  ジャンル5の本
ジャンル6  ジャンル6の本
全件数7件 前へ 1 2 3 次へ 

注)「2」「3」「次へ」にはリンクが作成されている。



(2ページ目) http://localhost/test_pagination7.php?page_id=2

ジャンル7  ジャンル7の本
全件数7件 前へ 1 2 3 次へ 

注)「前へ」「1」「3」「次へ」にはリンクが作成されている。



(3ページ目) http://localhost/test_pagination7.php?page_id=3

全件数7件 前へ 1 2 3 次へ 

注)「前へ」「1」「2」にはリンクが作成されている。



 http://localhost/test_pagination7.php?page_id=0
を直接入力した場合のみ表示される。

ジャンル1  ジャンル1の本
ジャンル2  ジャンル2の本
ジャンル3  ジャンル3の本
全件数7件 前へ 1 2 3 次へ 

注)「1」「2」「3」「次へ」にはリンクが作成されている。

お礼日時:2019/04/02 18:13

ざっくり書くとこんな感じ



<a href="?page=0&per=3">1</a>
<a href="?page=1&per=3">2</a>
<a href="?page=2&per=3">3</a><br>
<?PHP
$page=filter_input(INPUT_GET,"page",FILTER_VALIDATE_INT,["options"=>["default"=>0]]);
$per=filter_input(INPUT_GET,"per",FILTER_VALIDATE_INT,["options"=>["default"=>3]]);

try{
$dsn = 'mysql:host=localhost; dbname=mydb;charset=utf8;';
$user = 'root';
$password = '***';
$pdo = new PDO($dsn, $user,$password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql="SELECT count(*) as cnt FROM book1";
$stmt = $pdo->query($sql);
$cnt=$stmt->fetch(PDO::FETCH_ASSOC)["cnt"];
print "データ数:".$cnt."<br>\n";

$sql="SELECT genre,book FROM book1 ORDER BY id LIMIT :page,:per";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(":page", $page*$per, PDO::PARAM_INT);
$stmt->bindValue(":per", $per, PDO::PARAM_INT);
$stmt->execute();
$rows=$stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($rows);
}catch(PDOException $e){
die($e->getMessage());
}
?>
    • good
    • 0

ごめんなさい、最後の一行間違えました。



x $res_array = array_chunk($data,MAX);

o $res_array = array_chunk($res_array,MAX);
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

いったん、SELECT結果を全部配列に入れる、というのは頭の中では何となくイメージできるのですが、完全には理解できず、実際に修正したところ、うまくいきません。

日本語での説明部分を具体的にPHPで表現する方法がわかりません。
もし、よろしければ


xxxxxxxxxxxxxxxxxxxxxxx  の部分を  ○○○○○○○○○○○○○  に修正

*********************  の部分を  △△△△△△△△△△△△△  に修正

-----------------------------  の部分を  ################  に修正

という感じでご回答いただけないでしょうか。

お礼日時:2019/04/02 11:23

なんか、極力そのロジック活かす方向で考えてたんですが面倒そうなんで、こういう考え方はどうですか?



$res_array = array();
while($kekka = $re->fetch()){
$res_array[] = $kekka;
}
$res_array = array_chunk($data,MAX);

一旦配列にSELECT結果を全部配列 $res_array に入れて、その配列をページあたりの件数で分割する。
そうしとけば、$res_array[$_GET['page_id']]で現在のページの一覧が取れる。
後はcount($res_array)でページ数も取れるし、後はよしなにって感じでどうでしょう。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報