はじめに
ページネーションは、データ駆動型アプリケーションを構築する上で重要な概念です。データベースからレコードを抽出する際、大量のレコードが取得されることがあります。例えば、アクティブなユーザーや特定の場所に属するユーザーのクエリを実行すると、数百、あるいは数千もの大量のユーザーが返されることがあります。この膨大な数のレコードを単一のウェブページに表示することは、ユーザーを圧倒し、ユーザーエクスペリエンスの滑らかさを損なう可能性があるため、ユーザーフレンドリーな解決策とは言えません。
したがって、好ましい選択肢はレコード数を制限することです。これがページネーションの概念です。言い換えれば、レコード数をページに分割し、そのページを表示します。1つのページには、フロントエンドに表示可能な10件、15件、あるいはその他の適切な件数のレコードを含めることができます。
ページネーションはアプリケーションの全体的なユーザーエクスペリエンスを向上させるだけでなく、取得するレコード数を減らすことができるため、アプリケーションの高速化にもつながります。これにより、クライアントとサーバー間でネットワークを介して転送されるデータ量が減り、レイテンシ時間が短縮されます。
このチュートリアルでは、データベースに接続するPHPコードを作成し、MySQLデータベースとそのLIMIT句を使用してページネーションを実装します。.
前提条件
このチュートリアルを進めるには、以下が必要です。
-
稼働中の最新バージョンのUbuntu。サポートが必要な場合は、Ubuntuサーバーのセットアップ方法チュートリアルを参照してください。
-
また、PHPとMySQLがインストールされている必要があります。PHPとMySQLをセットアップするには、次のチュートリアルがあります:LAMPスタックのセットアップ – Linux Apache MySQL PHP.
ステップ 1 — データベースユーザーとテストデータベースのセットアップ
このチュートリアルでは、MySQLデータベースとのデータベース接続を確立し、レコードを取得します。これらのレコードは、table要素を使用してHTMLページに表示されます。接続を確立してレコードを表示するために、PHPスクリプトを使用します。データベース接続の準備ができたら、ページネーションありとページネーションなしでアプリケーションをテストします。このようにテストすることで、ページネーションが実際にどのように機能するかを理解することができます。
MySQLデータベースに接続するには、サンプルのMySQLデータベースと、MySQLデータベースに接続するためのユーザーの認証情報が必要になります。このステップでは、MySQLデータベース用の非rootユーザー、サンプルデータベース、およびPHPスクリプトをテストするためのテーブルを作成します。
まず、サーバーにログインします。次に、以下のコマンドを使用してMySQLサーバーにログインします。
|
1 |
mysql> sudo mysql -u root -p |
rootユーザーのパスワードを求められます。パスワードを入力し、 Enter キーを押して進めます。次に、チュートリアルで使用する test_db という名前のサンプルデータベースを作成します。新しいデータベースを作成するには、以下のコマンドを実行します:
|
1 |
mysql> Create database test_db; |
MySQLサーバーから、1行が影響を受けたという出力が表示されます。次に、このデータベース用の新しいユーザーを作成する必要があります。このユーザーにすべての権限を付与します。ただし、実際のアプリケーションを操作する場合は、権限を制限するようにしてください。このユーザーを test_user と呼びます。以下のコマンドで、 PASSWORD を強力なパスワードに置き換えてください:
|
1 |
mysql> GRANT ALL PRIVILEGES ON test_db.* TO 'test_user'@'localhost' IDENTIFIED BY 'PASSWORD'; |
ユーザーが作成されたら、権限をフラッシュ(反映)します:
|
1 |
mysql> FLUSH PRIVILEGES; |
これで test_user と test_db の両方の準備が整いました。 test_db を使用してテーブルを作成します。 test_db に切り替えるには、以下のコマンドを実行します:
|
1 |
mysql> Use test_db; |
出力でデータベースが変更されたことを確認したら、テーブルを作成する準備は完了です。製品を保持するための Products という新しいテーブルを作成します。この目的のために、このテーブルには2つの列のみが必要です: product_id と product_name です。 product_id を AUTO_INCREMENT、これにより新しい商品を追加するたびに値が増加します。もう一方の列は product_name と呼ばれ、商品の名前を保存するために使用されます。この product_name 列は、各商品を名前で区別するために使用されます。
|
1 |
mysql> Create table products (product_id BIGINT PRIMARY KEY AUTO_INCREMENT, product_name VARCHAR(50) NOT NULL ) Engine = InnoDB; |
次に、いくつかの products をこの新しく作成したテーブルに追加します。これを行うには、以下のコマンドを実行します:
|
1 2 3 4 5 6 7 8 9 10 |
mysql> Insert into products(product_name) values ('WIRELESS MOUSE'); mysql> Insert into products(product_name) values ('BLUETOOTH SPEAKER'); mysql> Insert into products(product_name) values ('GAMING KEYBOARD'); mysql> Insert into products(product_name) values ('320GB FAST SSD'); mysql> Insert into products(product_name) values ('17 INCHES TFT'); mysql> Insert into products(product_name) values ('SPECIAL HEADPHONES'); mysql> Insert into products(product_name) values ('HD GRAPHIC CARD'); mysql> Insert into products(product_name) values ('80MM THERMAL PRINTER'); mysql> Insert into products(product_name) values ('HDMI TO VGA CONVERTER'); mysql> Insert into products(product_name) values ('FINGERPRINT SCANNER'); |
これらの商品がテーブルに入力されたことを確認するには、以下のコマンドを実行します:
|
1 |
mysql> select * from products; |
上記で入力した商品が表示されれば、次に進む準備は完了です。以下のコマンドを使用してMySQLデータベースを終了します:
|
1 |
mysql> quit; |
MySQLデータベースをセットアップし、テストデータを入力したので、このデータベースに接続してレコードを取得するPHPスクリプトをコーディングする準備が整いました。
ステップ 2 – ページネーションなしでのレコードの取得と表示
上記で説明したように、まずはページネーションなしでレコードを表示します。MySQLデータベースに接続してレコードを取得するPHPスクリプトを作成します。上記で作成した test_db に、 test_user を使用して接続し、レコードを取得します。
現在、私たちの products テーブルには10個のレコードしかありません。多くのユーザーにとって、ページネーションが必要かどうかが明確ではないかもしれません。しかし、ページネーションなしでアプリケーションをテストすることで、それがアプリケーション全体の体験にどのように役立つかが詳しくわかります。また、データを分割することが、より良いユーザー体験を作成し、サーバーの負荷を軽減するのにどのように役立つかも理解できます。
PHPサーバーのウェブサイトフォルダのドキュメントルートで、以下のコマンドを実行します:
sudo nano /var/www/html/pagination_test.php
次に、このファイルに以下の内容を追加します。必ず PASSWORD を、お使いの次のユーザーのパスワード値に置き換えてください: test_user:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php try { $pdo = new PDO("mysql:host=localhost;dbname=test_db", "test_user", "PASSWORD"); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); $sql = "select * from products"; $stmt = $pdo->prepare($sql); $stmt -> execute(); echo "<table border='1' align='center'>"; while (($row = $stmt -> fetch(PDO::FETCH_ASSOC)) !== false) { echo "<tr>"; echo "<td>".$row['product_id']."</td>"; echo "<td>".$row['product_name']."</td>"; echo "</tr>"; } echo "</table>"; } catch(PDOException $e) { echo $e->getMessage(); } ?> |
ファイルを保存します。次に進む前に、上記で行ったことをまとめます。
-
まず、MySQLデータベースに接続しました。そのために、PHP Data Object (PDO)ライブラリを使用しました。MySQLデータベースに接続するために、上記で使用したMySQLユーザーの認証情報を使用しました。PDOは、データベースへの接続に使用される非常に便利なライブラリです。データアクセスレイヤーのコーディングを容易にし、アプリケーションを大幅にリファクタリングすることなく、さまざまなデータベースに接続できるようにします。PDOはプリペアドステートメントを使用するため、セキュリティが損なわれないことが保証されます。したがって、クエリは安全に実行されます。
-
次に、 PDO APIを使用して、 select * from products文を実行しました。 $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false)は、PHPのデータ型がデータベースと同じであることを保証します。したがって、 product_idと product_nameはそれぞれ整数と文字列として表示されます。
-
The $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);は、エラーが発生した場合に例外をスローするようにPDOに指示します。これにより、 try … catchブロックで例外を簡単にキャッチし、必要に応じて処理できます。
スクリプトの準備ができたので、これを実行する必要があります。そのためには、ブラウザを開いて次のURLにアクセスしてください: /var/www/html/pagination_test.php。URLにサーバーのIPを付加してください。ローカルで実行している場合、URLは次のようになります: http://localhost/var/www/html/pagination_test.php.
以下のような出力が表示されます:

ここでは、商品が返され、ページに表示されます。さて、何百もの商品があった場合を想像してみてください。データを取得してページに表示するために長いループが発生することになります。これにより、ページの読み込み時間が増加します。
次のセクションでは、PHPスクリプトを修正し、MySQLの LIMIT句を含めます。これにより、大量のレコードが表示される問題が解決されます。ユーザーがページ間を移動できるように、ページネーションリンクを追加します。
ステップ 3 – PHPを使用したページネーションの設定
このステップでは、PHPを使用してページネーションを設定し、複数のテーブルを使用してデータを表示します。ページネーションに対応するために、前のステップでコーディングしたスクリプトを修正します。
MySQLデータベースの LIMIT句を使用します。これをスクリプトに追加する前に、MySQLの LIMIT構文の例を見てみましょう。
|
1 |
mysql> Select [column1, column2, column n...] from [table name] LIMIT offset, records; |
上記のステートメントでは、 LIMIT句に offsetと records引数があることがわかります。 offsetはスキップするレコード数を示し、 recordsは1ページあたりに表示する、またはデータベースから取得する最大レコード数を示します。
ページネーションの仕組みがわかったところで、どのように実装するかを見てみましょう。1ページあたり3つのレコードを表示します。したがって、データベースに10個のレコードがある場合、総レコード数を1ページあたりのレコード数で割ることで、4ページになります。結果が整数にならない可能性があるため、PHPの Ceil関数を使用して、最も近い整数に切り上げて整数値の結果を取得します。以下は、 Ceil関数を示す簡単なコードスニペットです。
|
1 |
$total_pages=ceil($total_records/$per_page); |
次に、ページネーションのコードを追加します。ページネーションを有効にしてナビゲーションリンクを追加するには、 /var/www/html/pagination_test.phpファイルを以下のコマンドを使用して開きます:
|
1 |
$ sudo nano /var/www/html/pagination_test.php |
次に、このファイルの内容を以下のコードに置き換えます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
<?php try { $pdo = new PDO("mysql:host=localhost;dbname=test_db", "test_user", "PASSWORD"); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); /* ページング情報の開始 */ $page = 1; if (isset($_GET['page'])) { $page = filter_var($_GET['page'], FILTER_SANITIZE_NUMBER_INT); } $per_page = 3; $sqlcount = "select count(*) as total_records from products"; $stmt = $pdo->prepare($sqlcount); $stmt->execute(); $row = $stmt->fetch(); $total_records = $row['total_records']; $total_pages = ceil($total_records / $per_page); $offset = ($page-1) * $per_page; /* ページング情報の終了 */ $sql = "select * from products limit :offset, :per_page"; $stmt = $pdo->prepare($sql); $stmt->execute(['offset'=>$offset, 'per_page'=>$per_page]); echo "<table border='1' align='center'>"; while ( ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) !== false) { echo "<tr>"; echo "<td>".$row['product_id']."</td>"; echo "<td>".$row['product_name']."</td>"; echo "</tr>"; } echo "</table>"; /* ナビゲーションの開始 */ echo "<table border='1' align='center'>"; echo "<tr>"; if ($page-1 >= 1) { echo "<td><a href=".$_SERVER['PHP_SELF']."?page=".($page - 1).">前へ</a></td>"; } if ($page+1 <= $total_pages) { echo "<td><a href=".$_SERVER['PHP_SELF']."?page=".($page + 1).">次へ</a></td>"; } echo "</tr>"; echo "</table>"; /* ナビゲーションの終了 */ } catch(PDOException $e) { echo $e->getMessage(); } ?> |
以下はこのコードの概要です:
-
現在表示しているページに関する情報を保持する必要があります。このために使用するのが、 $page 変数です。この $page 変数は、 $_GET[‘page’] 変数を使用して、現在表示しているページを取得するために使用されます。
-
次に、1ページに表示する件数を指定する必要があります。このために使用するのが、 $per_page 変数。ここでは、1ページあたり3つの製品のみを表示しています。
-
上記で説明したように、データベースに存在するレコードの総数を取得する必要があります。これは、総ページ数を特定するために必要です。 $total_records 変数がこの情報を保持します。
-
最後に、スキップするレコード数を知る必要があります。例えば、2ページ目にいる場合、データベースの最初の3つのレコードをスキップする必要があります。これには $offset 変数を使用してこの情報を保持します。この情報は、ページが読み込まれるたびに、次の数式を使用して計算されます。 $offset=($page-1)*$per_page。他の件数を表示する必要がある場合は、 $per_page 変数で値を指定できます。
-
ナビゲーションボタンを表示するには、以下のコードを使用します。
|
1 2 3 4 5 6 7 8 9 10 |
. . . if( $page-1>=1) { echo "<td><a href=".$_SERVER['PHP_SELF']."?page=".($page-1).">Previous</a></td>"; } if( $page+1<=$total_pages) { echo "<td><a href=".$_SERVER['PHP_SELF']."?page=".($page+1).">Next</a></td>"; } . . . |
ロジックとしては、 $page が現在のページを保持するために使用されます。ページに「前へ」のオプションを表示したい場合、スクリプトは $page 変数の値から1を引きます。結果が1以上の場合、ページに「前へ」のオプションが表示されます。
同様に、「次へ」のオプションを表示するには、 $page 変数に1を加算します。ここでは、加算の結果が $total_pages 変数の総ページ数を超えないようにしています。
その後、ページを確認します。ブラウザを開き、以前使用したURLを使用してページにアクセスします。
|
1 |
http://your_server_ip/pagination_test.php |
以下のような出力が表示されます。



これで、PHPスクリプトでMySQLの LIMIT 句を使用したページネーションの実装が完了しました。アプリケーションにページネーションを実装することで、複数のレコードをより適切にナビゲートできるようになります。
結論
このチュートリアルでは、Ubuntu上でPHPとMySQLを使用してページネーションを実装する方法を説明しました。これらの手順を活用することで、大量のレコードをページごとに分割して適切に表示し、効果的に操作できるアプリケーションを構築できます。
さらに、UbuntuでのPHPとMySQLに関する役立つチュートリアルが他にもあります。
- Ubuntu 18.04でphpMyAdminをインストールしてセキュリティを確保する方法
- MariaDBまたはMySQLのRootパスワードをリセットする方法
- CloudSigmaチュートリアル:サーバーにMySQLをセットアップする方法とMySQLの基本
Happy Computing!
コメント
コメントはまだありません。最初のコメントを投稿しましょう。