広告

【PHP】データを10件ずつ表示するのにLIMIT句でやってみた

2019年10月6日

PHPでLIMIT句を使って、テーブルに登録されているデータを10件ずつデータ表示する方法を紹介します。

すぐに最終コードを見る↓

補足
PHPでrequireの使って他ファイルのプログラムを呼び出す方法を知っておくとこの記事の理解も捗ります!
require
php-require
PHPでrequireの使い方。他ファイルのプログラムを呼び出す方法

PHPで「require」を使って他ファイルからプログラムを呼び出す方法を記してます。 補足 PHPのis_numer ...

続きを見る

PHPで10件ずつ表示するには

PHPでデータベースに登録した値を10件ずつ表示するには、ページネーションの考え方を元に実装します。

ページネーションとは
表示するページ割・ページ分割のこと。1ページの情報量を減らして見やすくしてあげる効果があります。

今回はサンプルとして「Pagination」というフォルダに、

  1. input.html(任意の値を入力するフォーム)
  2. connect.php(データベースへ値を登録するファイル)
  3. index.php(データーベースへ登録された値を表示するファイル)
  4. request.php(登録した値の詳細画面を表示するファイル)

といったファイルを設けて、ページネーションの実装を行ってみました。

Paginationフォルダと4つのファイル

input.htmlファイルのコード

<main>
<h2>部品名を入力してください。</h2>
<form action="index.php" method="post">
<textarea name="buhin" cols="40" rows="3" placeholder="登録する部品名を入力"></textarea><br>
<button type="submit" name="button">登録する</button>
</form>
</main>

connect.phpファイルのコード(requireの対象ファイル)

<?php
try { // データーベースtestへ接続
$db = new PDO('mysql:dbname=test;host=localhost;charset=utf8','root','root');
} catch (PDOException $e) {
// 接続できなかったらエラー表示
echo 'DB接続エラー!:' . $e->getMessage();
}
?>

index.phpファイルのコード

<main>
<h2>登録した部品名一覧</h2>
<?php
require('connect.php');
// 部品登録テーブルの部品名の値を降順に取得して$entryに格納
$entry = $db->query('SELECT * FROM 部品登録 ORDER BY 部品名 DESC');
?>
<article>
<?php while($resister = $entry->fetch()): ?><!-- $entryの値をfetchで1件ずつ取得して$resistorへ格納 -->
<a href="request.php"><?php print(mb_substr($resister['部品名'],0,50)); ?></a>
<time><?php print($resister['登録日']); ?></time>
<hr size='3' color="#a9a9a9" width="450" align="left">
<?php endwhile; ?>
</article>
</main>

request.phpファイルのコード

<main>
<h2>登録した部品名の詳細画面</h2>
<?php
require('connect.php');
//安全に処理するためにprepareとREQUEST変数で処理する
$Data = $db->prepare('SELECT * FROM 部品登録 WHERE id=?');
$Data->execute(array($_REQUEST['id']));
$hyouji = $Data->fetch();
?>
<article>
<pre><?php print($hyouji['部品名']);?></pre>
<a href="index.php">一覧画面へ戻る</a>
</article>
</main>

また、phpMyAdminのデータベーステーブル「部品登録」に、既に10件以上の値が登録されていることを想定し進めていきます。

データベースに登録された値

ちなみにこの状態でindex.phpを表示すると、以下のように10件以上の値が画面表示されてしまいます↓

10件以上の内容が表示された状態

手順1. LIMIT句を設ける

最初にindex.phpのコードの中で、テーブルから値を取得するSELECT文箇所に、

$entry = $db->query('SELECT * FROM 部品登録 ORDER BY 部品名 DESC');

「LIMIT句」を設けて画面に表示する件数を制限します。

LIMIT句とは

SELECT文で取得するデータ数(行数)を指定することができます
例:SELECT カラム名 FROM テーブル名 LIMIT (表示させる行数);

今回は「ORDER BY」と「DESC」にてデータを降順にソートしながら、LIMIT句にてデータ表示数を10に指定しました。

$entry = $db->query('SELECT * FROM 部品登録 ORDER BY 部品名 DESC LIMIT 0,10');

LIMIT句を設けて実行した結果

入力フォームに適当な値を入力して登録すると、

適当な値を入力

10件の登録したデータの値が表示されます。

10件に制限された画面が表示された

ただLIMIT句では画面表示するデータ件数を制限しただけにすぎず、このままでは20件以上あるデータのうち10件しか表示されてない状態なんですよね。

あひる
あひる
10件表示された!けど、10件目より後のデータが表示されてない...

手順2. bindParamで疑問府にパラメータを紐付けする

10件目以降のデータを表示させるために、index.phpにbindParam(詳細は補足↓)を使った以下コードを追記。

$entry->bindParam(1, $_REQUEST['page'], PDO::PARAM_INT);

またユーザーが値を入力することを想定し、queryメソッドからprepareメソッドに書き換え

参考記事:PHP・prepareメソッドの使い方

prepare
MySql-prepare-php-2-768x432
【MySQL】PHPでprepareを使って安全にデータベースへ登録する方法

前回はフォームに入力した値をPHPでデータベースへ登録する方法を紹介しました。 しかし! 入力される値によってはSQLを ...

続きを見る

queryをprepareに置き換えて、bindParamで疑問府に値を格納しexecuteメソッドの前に挿入します↓

$entry = $db->prepare('SELECT * FROM 部品登録 ORDER BY 部品名 DESC LIMIT ?, 10');
$entry->bindParam(1, $_REQUEST['page'], PDO::PARAM_INT);
$entry->execute();

index.phpファイルのコード(bindParam設置済)

<main>
<h2>登録した部品名一覧</h2>
<?php
require('connect.php');
// 部品登録テーブルの部品名の値を降順に取得して$entryに格納
$entry = $db->prepare('SELECT * FROM 部品登録 ORDER BY 部品名 DESC LIMIT ?, 10');
$entry->bindParam(1,$_REQUEST['page'], PDO::PARAM_INT);
$entry->execute();
?>
<article>
<?php while($resister = $entry->fetch()): ?><!-- $entryの値をfetchで1件ずつ取得して$resistorへ格納 -->
<a href="request.php"><?php print(mb_substr($resister['部品名'],0,50)); ?></a>
<time><?php print($resister['登録日']); ?></time>
<hr size='3' color="#a9a9a9" width="450" align="left">
<?php endwhile; ?>
</article>
</main>

補足:bindParamとPARAM_INTの詳細

bindParamは疑問府プレースホルダ(クエスチョンマーク)に、値を格納することができます

以下引用メモ。

PDOStatement::bindParam

準備された SQL ステートメント中で、 対応する名前もしくは疑問符プレースホルダにパラメータをバインドします。

PDOStatement::bindValue() と異なり、 変数は参照としてバインドされ、PDOStatement::execute() がコールされたときのみ評価されます。

参照:PHP -PDOStatement::bindParam

またPDO::PARAM_INT を使うことで、整数のデータ型を表すことができます。

PDO::PARAM_INT (integer)

SQL INTEGER データ型を表します。

参照:PHP 定義済み定数

bindParam設置後URLパラメーターを変更した結果

index.phpにbindParamで作成したコードをexecuteメソッドの前に挿入したら、手順1の実行結果のURLパラメーターを Pagination/?page= に変更してみます。

URLパラメーター書き換え前

http://localhost:8888/Pagination/index.php

URLパラメーター書き換え後

http://localhost:8888/Pagination/?page=1

実行結果としては以下のようになりました↓
bindParamを設定・実行表示された結果1

文末の数字を2にすると...

http://localhost:8888/Pagination/?page=2

以下のように表示されます↓

bindParamを設定・実行表示された結果2

補足:LIMIT句で制限した値が表示されている

手順2の実行結果では、

  • page1を指定したのに8~19のデータが表示される
  • page2を指定したのに7~18のデータが表示される

といったように想定したページが表示できていません

理由は、LIMIT句でページ数を指定しているのではなく件数を指定しているから。

$entry = $db->query('SELECT * FROM 部品登録 ORDER BY 部品名 DESC LIMIT 0,10');

たとえば上記コードのLIMIT句で開始される番号は、 10 × (page -1)と計算することで確認することができます

補足すると以下のようなイメージです。

指定したpage LIMIT句の結果 スタートの件数
page=1 LIMIT 0,10 10 * (page-1) ↓
10 * (1 -1) = 0件目〜
page=2 LIMIT 10,10 10 * (page-1) ↓
10 *(2-1) = 10件目〜
page=3 LIMIT 20,10 10 * (page-1) ↓
10 *(3-1) = 20件目〜
注意!
データベースのレコードでは、数値型のフィールド[規定値]プロパティの初期値は「0」となっているため、新規レコードに最初は「0」が入力されます。
※[規定値]プロパティの「0」を削除することで、新規レコードの内容を表示させないようにすることができます)

指定したページ数から、>1を引いた数 × 制限する数(今回は10)で、表示スタートの件数が分かるようになるんですね。

そこで、スタートの件数を変数に格納して指定してあげます。

手順3. bindParamのパラメーターをLIMIT句に渡す

bindParamに入れたパラメーター $_REQUEST['page'] を、変数で受け取る処理に変更します。

変更前

$entry->bindParam(1, $_REQUEST['page'], PDO::PARAM_INT);

変更後

$page = $_REQUEST['page'];
$start = 10 * ($page-1);
$entry->bindParam(1, $start, PDO::PARAM_INT);

bindParamを変数格納後のindex.phpファイルのコード

<main>
<h2>登録した部品名一覧</h2>
<?php
require('connect.php');
$page = $_REQUEST['page'];
$start = 10 * ($page - 1);
// 部品登録テーブルの部品名の値を降順に取得して$entryに格納
$entry = $db->prepare('SELECT * FROM 部品登録 ORDER BY 部品名 DESC LIMIT ?, 10');
$entry->bindParam(1,$start, PDO::PARAM_INT);
$entry->execute();
?>
<article>
<?php while($resister = $entry->fetch()): ?><!-- $entryの値をfetchで1件ずつ取得して$resistorへ格納 -->
<a href="request.php"><?php print(mb_substr($resister['部品名'],0,50)); ?></a>
<time><?php print($resister['登録日']); ?></time>
<hr size='3' color="#a9a9a9" width="450" align="left">
<?php endwhile; ?>
</article>
</main>

これで実行してみると、 Pagination/?page=1 では以下のように表示されます。

Pagination/?page=1の表示結果

Pagination/?page=2 を実行すると、以下のように表示されることが確認できました。

Pagination/?page=2の表示結果

OYAKUN
OYAKUN
page=2は狙いどおりだけど、page=1の表示が想定とちょっとちがう...

まとめ

ちょっと Pagenation/?page=1 の表示結果が解せないので、解決したらサクッと追記するつもりです。(多分...)

今回は長くなってしまったので、次回はサクッとissetを利用してURLパラメーターに入力される値のチェックを行っていきます!

入力値のチェック
URL-parameter
【PHP】URLパラメーターをチェックする方法

PHPにてURLパラメーターをチェックして、エラーだったらデータ1ページ目の値を返す方法を記してます。 すぐにサンプルコ ...

続きを見る

関連記事:PHPでrequireの使い方。他ファイルのプログラムを呼び出す方法
関連記事:PHPでURLパラメーターを指定して利便性をあげる方法
関連記事:PHPの$_REQUESTでMySQLから任意のデータを取得する方法