Ubuntu18.04でPHPを使用してMySQLにページネーションを実装する方法
序章
ページネーションは、レコードセットで返される行の数を個別の整然としたページに制限して、それらの間を簡単に移動できるようにするという概念です。したがって、大きなデータセットがある場合は、各ページで特定の数の行のみを返すようにページネーションを構成できます。 たとえば、ページに表示されるアイテムの数を減らすことで、Webストアに数千の製品が含まれている場合に、ユーザーがすべての製品を表示する必要がなくなる可能性が高いため、ページネーションはユーザーを圧倒するのを防ぐのに役立ちます。 もう1つの例は、モバイルデバイスでレコードを表示するアプリケーションです。 このような場合にページネーションを有効にすると、レコードが複数のページに分割され、画面に収まりやすくなります。
エンドユーザーにとっての視覚的な利点に加えて、ページネーションは、一度に返されるレコードの数を減らすため、アプリケーションを高速化します。 これにより、クライアントとサーバー間で送信する必要のあるデータが制限され、RAMなどのサーバーリソースを保護できます。
このチュートリアルでは、 PHP スクリプトを作成してデータベースに接続し、 MySQL LIMIT句を使用してスクリプトへのページネーションを実装します。
前提条件
始める前に、次のものが必要になります。
- Ubuntu 18.04を使用した初期サーバーセットアップに従ってセットアップされた1つのUbuntu18.04サーバー(sudo非rootユーザーを含む)。
- システムにインストールされているApache、MySQL、およびPHP。 Linux、Apache、MySQL、PHP(LAMP)スタックをUbuntu18.04にインストールする方法に関するガイドに従うことができます。
ステップ1—データベースユーザーとテストデータベースの作成
このチュートリアルでは、MySQLデータベースに接続し、レコードをフェッチして、テーブル内のHTMLページに表示するPHPスクリプトを作成します。 PHPスクリプトは、Webブラウザから2つの異なる方法でテストします。 まず、ページネーションコードなしでスクリプトを作成して、レコードがどのように表示されるかを確認します。 次に、PHPファイルにページナビゲーションコードを追加して、ページネーションが実際にどのように機能するかを理解します。
PHPコードには、認証のためのMySQLユーザーと、接続するためのサンプルデータベースが必要です。 このステップでは、MySQLデータベース、サンプルデータベース、およびPHPスクリプトをテストするためのテーブルの非rootユーザーを作成します。
サーバーへのログインを開始します。 次に、次のコマンドを使用してMySQLサーバーにログインします。
- sudo mysql -u root -p
MySQLサーバーのrootパスワードを入力し、 ENTER
続ける。 次に、MySQLプロンプトが表示されます。 サンプルデータベースを作成するには、これを呼び出します test_db
このチュートリアルでは、次のコマンドを実行します。
- Create database test_db;
次の出力が表示されます。
OutputQuery OK, 1 row affected (0.00 sec)
次に、を作成します test_user
ユーザーにすべての権限を付与します test_db
. 交換 PASSWORD
強い価値を持つ:
- GRANT ALL PRIVILEGES ON test_db.* TO 'test_user'@'localhost' IDENTIFIED BY 'PASSWORD';
OutputQuery OK, 1 row affected (0.00 sec)
次のコマンドでMySQL特権をリロードします。
- FLUSH PRIVILEGES;
OutputQuery OK, 1 row affected (0.00 sec)
次に、に切り替えます test_db
データベースで直接作業を開始します test_db
データベース:
- Use test_db;
OutputDatabase changed
次に、 products
テーブル。 この表にはサンプル製品が含まれています。このチュートリアルでは、データに必要な列は2つだけです。 The product_id
列は、各レコードを一意に識別するための主キーとして機能します。 この列はに設定されます AUTO_INCREMENT
新しいを生成するには product_id
挿入されたアイテムごとに。 を使用します product_name
各アイテムを名前で区別するフィールド:
- Create table products (product_id BIGINT PRIMARY KEY AUTO_INCREMENT, product_name VARCHAR(50) NOT NULL ) Engine = InnoDB;
OutputQuery OK, 0 rows affected (0.02 sec)
10個のテスト製品をに追加するには products
テーブルは次のSQLステートメントを実行します。
- Insert into products(product_name) values ('WIRELESS MOUSE');
- Insert into products(product_name) values ('BLUETOOTH SPEAKER');
- Insert into products(product_name) values ('GAMING KEYBOARD');
- Insert into products(product_name) values ('320GB FAST SSD');
- Insert into products(product_name) values ('17 INCHES TFT');
- Insert into products(product_name) values ('SPECIAL HEADPHONES');
- Insert into products(product_name) values ('HD GRAPHIC CARD');
- Insert into products(product_name) values ('80MM THERMAL PRINTER');
- Insert into products(product_name) values ('HDMI TO VGA CONVERTER');
- Insert into products(product_name) values ('FINGERPRINT SCANNER');
次の出力が表示されます。
OutputQuery OK, 1 row affected (0.02 sec)
次のコマンドを実行して、製品がテーブルに挿入されたことを確認します。
- select * from products;
2つの列内の出力に製品が表示されます。
Output+------------+-----------------------+
| product_id | product_name |
+------------+-----------------------+
| 1 | WIRELESS MOUSE |
| 2 | BLUETOOTH SPEAKER |
| 3 | GAMING KEYBOARD |
| 4 | 320GB FAST SSD |
| 5 | 17 INCHES TFT |
| 6 | SPECIAL HEADPHONES |
| 7 | HD GRAPHIC CARD |
| 8 | 80MM THERMAL PRINTER |
| 9 | HDMI TO VGA CONVERTER |
| 10 | FINGERPRINT SCANNER |
+------------+-----------------------+
10 rows in set (0.00 sec)
MySQLを終了します:
- quit;
サンプルデータベース、テーブル、およびテストデータが配置されたら、Webページにデータを表示するためのPHPスクリプトを作成できるようになりました。
ステップ2—ページネーションなしでMySQLレコードを表示する
次に、前の手順で作成したMySQLデータベースに接続するPHPスクリプトを作成し、Webブラウザーに製品を一覧表示します。 このステップでは、PHPコードはページ付けなしで実行され、分割されていないレコードが1つのページにどのように表示されるかを示します。 このチュートリアルでは、テスト目的で10個のレコードしかありませんが、ページ付けなしでレコードを表示すると、データをセグメント化することで最終的にユーザーエクスペリエンスが向上し、サーバーへの負担が軽減される理由がわかります。
次のコマンドを使用して、WebサイトのドキュメントルートにPHPスクリプトファイルを作成します。
- sudo nano /var/www/html/pagination_test.php
次に、次のコンテンツをファイルに追加します。 交換することを忘れないでください PASSWORD
に割り当てたパスワードの正しい値を使用して test_user
前のステップで:
<?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();
}
?>
を押してファイルを保存します CTRL+X
, Y
、 と ENTER
.
このスクリプトでは、ステップ1で作成したデータベース資格情報を使用して PDO(PHPデータオブジェクト)ライブラリを使用してMySQLデータベースに接続しています。
PDOは、データベースに接続するための軽量のインターフェースです。 データアクセス層はより移植性が高く、わずかなコードの書き直しでさまざまなデータベースで機能します。 PDOは、プリペアドステートメントをサポートしているため、セキュリティが強化されています。これは、クエリを安全な方法で高速化するための機能です。
次に、PDOAPIに実行するように指示します select * from products
ステートメントを作成し、ページ付けなしでHTMLテーブルに製品を一覧表示します。 この線 $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
データ型がデータベースに表示されるとおりに返されるようにします。 これは、PDOが product_id
整数として、 product_name
文字列として。 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
エラーが発生した場合に例外をスローするようにPDOに指示します。 デバッグを容易にするために、PHP内のエラーをキャッチしています try{}...catch{}
ブロック。
を実行するには /var/www/html/pagination_test.php
作成したPHPスクリプトファイルは、次のURLにアクセスして置き換えてください your-server-IP
サーバーのパブリックIPアドレスを使用します。
http://your-server-IP/pagination_test.php
製品の表が記載されたページが表示されます。
PHPスクリプトは期待どおりに機能しています。 1ページにすべての製品を一覧表示します。 何千もの製品がある場合、製品がデータベースからフェッチされてPHPページにレンダリングされるため、ループが長くなります。
この制限を克服するには、PHPスクリプトを変更し、MySQLを含めます LIMIT
表の下部にある句といくつかのナビゲーションリンクは、ページ付け機能を追加します。
ステップ3—PHPを使用したページネーションの実装
このステップの目標は、テストデータを複数の管理しやすいページに分割することです。 これにより、読みやすさが向上するだけでなく、サーバーのリソースをより効率的に使用できます。 前の手順で作成したPHPスクリプトを変更して、ページネーションに対応します。
これを行うには、MySQLを実装します LIMIT
句。 これをスクリプトに追加する前に、MySQLの例を見てみましょう。 LIMIT
構文:
- Select [column1, column2, column n...] from [table name] LIMIT offset, records;
The LIMIT
このステートメントの終わりに向かって示されているように、句は2つの引数を取ります。 The offset
valueは、最初の行の前にスキップするレコードの数です。 records
1ページに表示するレコードの最大数を設定します。
ページネーションをテストするには、ページごとに3つのレコードを表示します。 合計ページ数を取得するには、テーブルの合計レコードを、ページごとに表示する行で除算する必要があります。 次に、PHPを使用して、結果の値を最も近い整数に丸めます。 Ceil
次のPHPコードスニペットの例に示すように機能します。
$total_pages=ceil($total_records/$per_page);
以下は、完全なページネーションコードを含むPHPスクリプトの修正バージョンです。 ページネーションとナビゲーションコードを含めるには、 /var/www/html/pagination_test.php
ファイル:
- sudo nano /var/www/html/pagination_test.php
次に、次の強調表示されたコードをファイルに追加します。
<?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);
/* Begin Paging Info */
$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;
/* End Paging Info */
$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>";
/* Begin Navigation */
echo "<table border='1' align='center'>";
echo "<tr>";
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>";
}
echo "</tr>";
echo "</table>";
/* End Navigation */
} catch(PDOException $e) {
echo $e->getMessage();
}
?>
ファイルで、ページングを実行するために追加のパラメーターを使用しました。
$page
:この変数は、スクリプトの現在のページを保持します。 ページ間を移動すると、スクリプトは次の名前のURLパラメータを取得しますpage
を使用して$_GET['page']
変数。$per_page
:この変数は、ページごとに表示する最大レコードを保持します。 あなたの場合、各ページに3つの製品をリストします。$total_records
:製品を一覧表示する前に、SQLステートメントを実行して、ターゲットテーブル内のレコードの総数を取得し、それをに割り当てます。$total_records
変数。$offset
:この変数は、最初の行の前にスキップするレコードの合計を表します。 この値は、式を使用してPHPスクリプトによって動的に計算されます$offset=($page-1)*$per_page
. この式をPHPページネーションプロジェクトに適合させることができます。 変更できることを忘れないでください$per_page
ニーズに合わせて可変。 たとえば、次の値に変更できます50
ウェブサイトを運営している場合、またはモバイルデバイス用に別の金額を実行している場合は、ページごとに50個のアイテムを表示します。
繰り返しますが、ブラウザでIPアドレスにアクセスし、置き換えます your_server_ip
サーバーのパブリックIPアドレスを使用します。
http://your_server_ip/pagination_test.php
ページの下部にいくつかのナビゲーションボタンが表示されます。 最初のページには、前へボタンは表示されません。 次へページボタンが表示されない最後のページでも同じことが起こります。 また、どのように page
各ページにアクセスすると、URLパラメータが変化します。
ページの下部にあるナビゲーションリンクは、ファイルからの次のPHPコードスニペットを使用して実現されます。
. . .
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
変数は現在のページ番号を表します。 次に、前のページを取得するために、コードはマイナスになります 1
変数から。 したがって、2ページ目にいる場合は、式 (2-1)
あなたに結果を与えるでしょう 1
これがリンクに表示される前のページになります。 ただし、次の値以上の結果が得られた場合にのみ前のページが表示されることに注意してください。 1
.
同様に、次のページに移動するには、次のページに1つ追加します。 $page
変数であり、次のことも確認する必要があります $page
に追加する結果 page
URLパラメータは、PHPコードで計算した合計ページ数を超えていません。
この時点で、PHPスクリプトはページ付けで機能しており、MySQLを実装できます。 LIMIT
より良いレコードナビゲーションのための句。
結論
このチュートリアルでは、Ubuntu18.04サーバー上のPHPを使用してMySQLでページングを実装しました。 PHPスクリプトを使用して、より大きなレコードセットでこれらの手順を使用して、ページネーションを含めることができます。 Webサイトまたはアプリケーションでページ付けを使用することにより、サーバー上でより優れたユーザーナビゲーションと最適なリソース使用率を作成できます。
ここから、次のチュートリアルを使用して、データベースおよびその他のデータベースタスクのさらなる最適化を検討できます。