前回まで作った管理テーブルに対し、データ件数が増えてきた場合を想定して、ページング処理を入れます。
前回までの、テーブル一覧部分のコードは以下のとおりです。
/** * 初期表示 */ function disp() { //データ一覧 echo <<< EOL <form action="" method="post"> <h2>データ一覧</h2> <input type='submit' name='submit[regist]' class='button-primary' value='新規登録' /> <div class="wrap"> <table class="wp-list-table widefat striped posts"> <tr> <th nowrap>ID</th> <th nowrap>名前</th> <th nowrap>登録日時</th> <th nowrap>詳細</th> <th nowrap>編集</th> </tr> EOL; global $wpdb; $tbl_name = $wpdb->prefix . 'sample_mst'; $sql = "SELECT * FROM {$tbl_name} ORDER BY id;"; $rows = $wpdb->get_results($sql); foreach($rows as $row) { echo "<tr>"; echo "<td>" . $row->id . "</td>"; echo "<td>" . $row->sample_name . "</td>"; echo "<td>" . $row->create_date . "</td>"; echo "<td>"; echo "<input type='submit' name='submit[detail][" . $row->id . "]'"; echo " class='button-primary' value='詳細' />"; echo "</td>"; echo "<td>"; echo "<input type='submit' name='submit[edit][" . $row->id . "]'"; echo " class='button-primary' value='編集' />"; echo "</td>"; echo "</tr>"; } echo "</table>"; echo "</div>"; echo "</form>"; }
このコードに対し、ページ処理を入れていきます。
まず、現在のページ番号をGETパラメータで受け渡す為、パラメータ取得用の変数を用意し、取得します。
$pageid = filter_input(INPUT_GET, 'pageid');
次に、1ページあたり、何件表示して次のページに移るのか、上限を決定します。
//1ページあたりの件数 $limit = 10;
次に、対象となるデータの総件数を取得します
//DBオブジェクトを用意 global $wpdb; //全件数取得 $tbl_name = $wpdb->prefix . 'sample_mst'; $sql = "SELECT count(*) AS CNT FROM {$tbl_name}"; $rows = $wpdb->get_results($sql); $recordcount = $rows[0]->CNT;
ここで、$recordcountという変数に総件数が格納されます。
次に、ページ遷移した時に、データベースからオフセットした値を取得する為に、SQL用にoffset値を決定します。
//offsetの値を決定 $offset = $pageid * $limit;
最後に、データベースにクエリを発行し、データを取得します。
ここのタイミングではlimit件数(10件ごと)にデータを区切って取得しています。
//offset と limitによる画面表示用のデータ取得 $sql = "SELECT * FROM {$tbl_name} ORDER BY id limit {$offset}, {$limit};"; //通常の取得方法(SQL実行結果を、オブジェクトとして取得) $rows = $wpdb->get_results($sql);
次にページ処理用のメソッドと、それに応じたパラメータを書いておきます。
$args = array( 'label' => __('Per Page'), 'default' => 10, 'option' => 'disp' ); $page_html = self::pagination($recordcount);
paginationというメソッド名は、function disp()の外側の任意の箇所に記述します。
function pagination($recordcount) { $count = $recordcount; $limit = 10; //レコード総数がゼロのときは何も出力しない if (0 === $count) { return ''; } //現在表示中のページ番号(ゼロスタート) $intCurrentPage = self::getCurrentPage(); //ページの最大数 $intMaxpage = ceil($count / $limit); //現在ページの前後3ページを出力 $intStartpage = (2 < $intCurrentPage) ? $intCurrentPage - 3 : 0; $intEndpage = (($intStartpage + 7) < $intMaxpage) ? $intStartpage + 7 : $intMaxpage; //url組み立て $urlparams = filter_input_array(INPUT_GET); $items = []; //ページURLの生成 //最初 $urlparams['page'] = filter_input(INPUT_GET, 'page'); $urlparams['pageid'] = 0; $items[] = sprintf('<span><a href="?%s">%s</a></span>' , http_build_query($urlparams) , '最初' ); //表示中のページが先頭ではない時 if (0 < $intCurrentPage) { $urlparams['pageid'] = $intCurrentPage - 1; $items[] = sprintf('<span><a href="?%s">%s</a></span>' , http_build_query($urlparams) , '前へ' ); } for ($i = $intStartpage; $i < $intEndpage; $i++) { $urlparams['pageid'] = $i; $items[] = sprintf('<span%s><a href="?%s">%s</a></span>' , ($intCurrentPage == $i) ? ' class="current"' : '' , http_build_query($urlparams) , $i + 1 ); } //表示中のページが最後ではない時 if ($intCurrentPage < ($intMaxpage - 1)) { $urlparams['pageid'] = $intCurrentPage + 1; $items[] = sprintf('<span><a href="?%s">%s</a></span>' , http_build_query($urlparams) , '次へ' ); } //最後 $urlparams['pageid'] = $intMaxpage - 1; $items[] = sprintf('<span><a href="?%s">%s</a></span>' , http_build_query($urlparams) , '最後' ); return $items; }
最終的に、$page_htmlという変数に、ページング出力用の情報が入るので、それを画面出力用に整形して、出力します。
//ページ部分の表示 echo "<div class='admin_pagination'>"; echo "<ul>"; foreach ($page_html as $key => $value) { echo "<li>" . $value . "</li>"; } echo "</ul>";
このままでは、文字列のみのページ表示になるので、cssでスタイルを調整します。
/* ページング処理 */ .admin_pagination ul li { display: inline-block; padding: 0px 1px 0px 1px; margin: 0px 3px 0px 3px; background-color: #DBDBDB; } .admin_pagination ul li .current a{ color: #FFFFFF; background-color: #666666; } .admin_pagination ul a { display: block; padding: 8px 10px 8px 10px; }
これで、テーブルに関連するページング処理の表示ができました。
出力結果は以下のようになります。
このように表示されます。
作っている最中に、気づきが遅かった部分がありました。
$wpdbのオブジェクトに対し、get_resultsメソッドを使ったSQL実行で、
offset、limitの処理を書いた場合、一般的なSQLの書き方では、
思うような抽出結果が得られませんでした。
SELECT * FROM テーブル名 OFFSET 10 LIMIT 5;
などと書くのはNGで、
SELECT * FROM テーブル名 LIMIT 10, 5;
のように書かないと、想定した出力結果が得られませんでした。
wpdbのget_resultsの仕様ページを見たのですが、明確な記載はありませんでした。
気づくまでに時間がかかってしまいました。
(2022/07/21 追記)
下記の箇所に不具合がありましたので、修正したコードに更新しました。
if文の「$intMaxpage」について、ページ遷移の仕方によっては不正な条件判定でしたので「($intMaxpage – 1)」という調整をしています。
根本的な対処とは言えませんが、訂正いたします。
■変更前
//表示中のページが最後ではない時 if ($intCurrentPage < $intMaxpage) { $urlparams['pageid'] = $intCurrentPage + 1; $items[] = sprintf('<span><a href="?%s">%s</a></span>' , http_build_query($urlparams) , '次へ' ); }
■変更後
//表示中のページが最後ではない時 if ($intCurrentPage < ($intMaxpage - 1)) { $urlparams['pageid'] = $intCurrentPage + 1; $items[] = sprintf('<span><a href="?%s">%s</a></span>' , http_build_query($urlparams) , '次へ' ); }
(2022/07/22 追記)
記載したソースコードの中で呼ばれているメソッド「getCurrentPage」の中身については、下記のメソッドになります。
/** * 現在のページ番号を取得する * @return int */ function getCurrentPage() { $pageid = esc_attr($_REQUEST["pageid"]); return $pageid; }
“管理画面のテーブル件数に応じて、ページングする” への3件のフィードバック
お疲れ様です。
//現在表示中のページ番号(ゼロスタート)
$intCurrentPage = self::getCurrentPage();
↑上記のgetCurrentPage()クラスメンバーメソッドの中身をしりたいです。
※ 今その行でエラーになっております。
ハン・スウェーさん
コメントいただきありがとうございます。
上記の「getCurrentPage()メソッド」についてはブログ記事内に記載しておりませんでした。
詳しくは、以下のようになります。
このメソッドを「function pagination($recordcount)」の前または後に記述すると動作するかと思います。
ご確認をお願いします。
ご回答、どうもありがとうございました。