【ドットインストール】ページング機能の解説


![完成図：ページング機能](https://qiita-image-store.s3.amazonaws.com/0/62881/2ff015ac-e6c5-2cab-9a10-ffbfccb078b6.gif "comment_table000.gif")

[ドットインストール](http://dotinstall.com/)のレッスン、「[PHPで作る「ページング機能」」 (全10回)](http://dotinstall.com/lessons/paging_php_v2)」の備忘録です。復習用にお使いください。

図解してみると複雑ではなく簡単なプログラムだということがわかるので、このレッスンはおすすめです。サクサクつくれると思います。今回はレッスン2からの解説です。

### GRANT文の基本書式 #02

[\#02 データベースの設定をしよう](http://dotinstall.com/lessons/paging_php_v2/8502)

GRANT文がわからなかったのでメモ。

```mysql
GRANT ALL ON dotinstall_paging_php.* TO dbuser@localhost IDENTIFIED BY '********';
```

上記がユーザーの権限を決めるGRANT文という意味です。grantとは「〜を与える」という意味です。

GRANT文の基本書式は次の通り。

```msqyl
GRANT '権限' ON 'データベース名.テーブルト名' TO 'ユーザー名@ホスト名';
```

権限とはSELECTやINSERTなど使える命令を決めることができます。今回の場合はALLですので、すべての命令が使えますね。レッスンで使われたGRANT文の内容を細かく見ていくと次のようなことを行っています。

* dbuserユーザーを作成
* dbuserユーザーに対して全ての権限(ALL)を付与。
* 権限の範囲はdotinstall_paging_phpデータベース内の全てのテーブル(dotinstall_paging_php.*)
* localhostというhostからの接続を許可する
* パスワードは'********'として設定

ちなみに、ONの次は命令できる範囲です。自分がどこまで通用するかということです。書き方は４通りあります。

```mysql
-- グローバルレベル:
GRANT 権限 ON *.* TO user;

-- データベースレベル:
GRANT 権限 ON db_name.* TO user;

-- テーブルレベル:
GRANT 権限 ON db_name.table_name TO user;

-- カラムレベル:
GRANT 権限 (カラム1, カラム2, ...) ON db_name.table_name TO user;
```

さらに理解を深めるには次のサイトのサンプルを見るといいです。

[Mysqlのユーザ/権限管理](http://d.hatena.ne.jp/yutakikuchi/20110609/1307581865)

### error_reportingは定数で設定 #04

[\#04 データ取得の準備をしよう](http://dotinstall.com/lessons/paging_php_v2/8504)

PDOを使ったデータベースへの接続はこちらの記事で解説しています。

[PDOを使ったPHPでのデータベース基本操作](http://program-blog.net/2013/10/pdo%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9Fphp%E3%81%A7%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C.html)

もう一つ、次の記事はざっくりとまとまっていてパッと内容を知ることが出来ます。

[はじめてPDOを使う人が知っておきたい 6 + 1 のポイント](http://kwsktr.hatenablog.com/entry/20110328/1301254129)

ここではerror_reportingについて見ていきます。

```php
error_reporting(E_ALL & ~E_NOTICE);
```

これでnotice以外のすべてのエラーを表示させています。警告以外ということですね。それと定数の意味は以下の通り。

定数        | 内容                                                             
--------- | ---------------------------------------------------------------
E_ALL     | サポートされる全てのエラーと警告。 PHP 5.4.0 より前のバージョンでは、E_STRICT レベルのエラーは除く。   
E_NOTICE  | 実行時の警告。エラーを発しうる状況に遭遇したことを示す。 ただし通常のスクリプト実行の場合にもこの警告を発することがありうる。
E_WARNING | 実行時の警告 (致命的なエラーではない)。スクリプトの実行は中断さ れません。                        

引用元：
<cite><a href="http://www.php.net/manual/ja/errorfunc.constants.php">PHPマニュアル：定義済み定数</a></cite>

警告表示は１つだけではないということ気をつけて下さい。なので、例として「E_WARNING」も載せておきました。引用元を見ていただければわかるのですが、かなり細かく分かれています。ですが、普段は使うことはないでしょう。

### DBからHTMLへレコードを展開する #05

[\#05 コメント一覧を表示しよう](http://dotinstall.com/lessons/paging_php_v2/8505)

[**foreach**](http://php.net/manual/ja/control-structures.foreach.php)

foreachについてですが、asは「〜として」という意味です。配列を１つずつ取り出して扱う場合の名前をasより後ろの変数名で決めます。

```php
foreach ('配列' as '変数名') {要素が1つ取り出す}
```

ちなみに、取り出される順番は決まっていません。キーが整数値だとしても、それらが順番に取り出される保証はありません。

[**array_push**](http://jp2.php.net/manual/ja/function.array-push.php)

```php
// 配列の最後に値を追加する
array_push(配列, 追加する値);
```

**データの取り出し**

queryメソッドの戻り値はPDOStatementオブジェクトですが、配列のように反復処理が可能です。なので、これを利用して、レコードセットを配列に変換しています。

```php
foreach ($dbh->query($sql) as $row) {
    array_push($comments, $row);
}
```

DBからHTMLへレコードを展開する流れは次の図の通りです。  
![図：DBからHTMLへレコードを展開](https://qiita-image-store.s3.amazonaws.com/0/62881/ddcbf2fc-ebcc-6e05-7f69-ea9122d67840.gif "comment_table001.gif")

### 何行目から何行データを取得するか #06

[\#06 1ページ目を表示しよう](http://dotinstall.com/lessons/paging_php_v2/8506)

句      | 機能        
------ | ----------
limit  | 何行取得するか   
offset | 何行目から取得するか

以下サンプルです。

```mysql
-- 5件目から10件取得
select * from comments limit 10 offset 4;
```

offsetは5ではなく、4です。行数は0から数えることに注意です。ちなみに、この文はoffsetを記述しずにlimitだけで書くことができます。

```mysql
select * from comments limit 4, 10;
```

# ページ数の管理 #07

[\#07 ページリンクを作ろう](http://dotinstall.com/lessons/paging_php_v2/8507)  
**total**

```php
// 全件取得
select count(*) from table
```

**pagetotal**

```
切り上げ（総ページ数 / １ページに表示するページ数）
```

### 正規表現 #08

[\#08 ページングを動作させてみよう](http://dotinstall.com/lessons/paging_php_v2/8508)  
正規表現について解説。これによりhtmlspecialcharsを使わなくて済みます。

```php
// パターンで指定した正規表現により、文字列を検索
preg_match('パターン', '文字列');

// 今回使用されたもの
preg_match('/^[1-9][0-9]*$/', $_GET['page']);
```

これは次に分類できます。。

1.  ^ ＝ 行頭
2.  [1-9] ＝ 1から9のうち1文字
3.  [0-9]* 1から9のうち0文字以上。
4.  $ ＝ 行末

各単語を理解した上で、文の意味を理解しましょう。

1.  行頭と行末に数字が挟まれているので、指定されているのは数字のみ.
2.  そして、その数字は1文字か2文字。
3.  1文字目は1から9のうちのどれか。
4.  2文字目は0から9のうちのどれか。

ちなみに*ではなく+だと１文字以上になります。

### ページリンクの作成 #09[\#09 ページリンクを使いやすく](http://dotinstall.com/lessons/paging_php_v2/8509)  
![図：３つのif文](https://qiita-image-store.s3.amazonaws.com/0/62881/4110f8a7-556e-ba08-22ab-3d2d47ebea8b.gif "comment_table002.gif")

### 件数の表示 #10

[\#10 件数などを表示させてみよう](http://dotinstall.com/lessons/paging_php_v2/8510)

```php
$from = $offset + 1;
$to = ($offset + COMMENTS_PER_PAGE) < $total ? ($offset + COMMENTS_PER_PAGE) : $total;
```

上記のコード  
を図にします

![図：件数の表示](https://qiita-image-store.s3.amazonaws.com/0/62881/6b3aa7e4-eb63-d600-0491-a357e20dd790.gif "comment_table003.gif")