20191112のMySQLに関する記事は7件です。

Docker-composeでMySQLの環境構築

なぜDocker-composeなのか?

他のコンテナと合わせて使用することを考えdocker-composeにしました。

構成

├── docker-compose.yml
├──.env
└── mysql
    └── initdb
        ├── 1_create_tables.sql
        └── 2_insert_seed.sql

docker-compose.yml

今回はブラウザからもアクセスできるようにしてMySQLをGUIでも操作できるようにしました。

docker-compose.yml
version: '3'

services:
  mysql:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    env_file: .env
    environment:
      TZ: "Asia/Tokyo"

    ports:
      - 3306:3306
    volumes:
      - mysql:/var/lib/mysql
      - ./mysql/initdb:/docker-entrypoint-initdb.d

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    restart: always
    ports:
      - 8080:80
    environment:
      PMA_ARBITRARY: 1
    env_file: .env
    depends_on:
      - mysql

volumes:
  mysql:

.env

docker-compose.ymlファイルに書くこともできますが分けた方がいいと思います!

MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test_db
MYSQL_USER: test
MYSQL_PASSWORD: test

PMA_HOST: mysql
PMA_USER: root
PMA_PASSWORD: root

初期化用sqlファイル

以下のファイルはあくまで一例です。
自由に書き換えて使用してください。

1_create_tables.sql

1_create_tables.sql
create table users
(
    id serial primary key,
    username varchar(50) unique not null,
    password varchar(50) not null,
    email varchar(255) unique not null
);

2_insert_seed.sql

2_insert_seed.sql
insert into users (username, password, email) values ('keid', 'keidpass', 'keid@developer.com');
insert into users (username, password, email) values ('jobs', 'jobspass', 'jobs@developer.com');
insert into users (username, password, email) values ('mask', 'maskpass', 'mask@developer.com');

起動

docker-compose.ymlファイルのあるディレクトリに移動してください

docker-compose up -d

コンテナに入ってMySQLを起動

docker-compose exec mysql bin/bash

root@30bffee726ff:/# mysql -u test -p
Enter password: test # 入力しても表示されません
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.18 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

phpMyAdminからアクセス

ブラウザなどからlocalhost:8080でphpMyAdminにアクセスできます。

まとめ

今回はDockerをやって欲しいというリクエストがありましたのでdocker-composeを使用してMySQL環境を構築してみました。
一人でも多くのクジラ信者が増えるようにdockerの良さが伝わればいいなと思います!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LAMP環境構築手順: 仮想環境

LAMP構築: Linux仮想環境作成 by Virtual Box

よくLAMPの仮想環境作成するので手順をまとめてみました。
多分Vagrantとか使ったらいいんでしょうけど、いろんな仮想環境を構築するのでなれもふくめて、まとめていきます。

手順通りにやれば1時間以内には終わると思います。
環境依存かもしれないのでisoファイルは似た感じのを使ったほうが苦労は少ないかと。

準備

VirtualBoxのインストール
isoファイルのダウンロード
今回使用するisoはCentOsのMinimalを使用しています。

仮想環境の作成

VirtualMachineを作成

  • タイプ: Linux
  • Version: RedHat(64bit)

それ以外の部分はOkOkOKで大丈夫です。

VirtualMachineの設定

  • Network: ブリッジアダプター

起動

マウスで操作できなければ、気合でTabを駆使して頑張ってください。
1. ディスクの選択: CentOS-7-x86_64-Minimal-1810.iso
2. INSTALLATION DESTINATION を選択して、Done で戻ると BeginInstallation が選択できる。
3. root password を設定する。
4. しばらくまつ。
5. Reboot ボタンが押せるようになると思うので、それで再起動しましょう

Linuxの設定

root ユーザでloginしてください。

Network接続

nmtuiを起動します。

nmtui
  1. Edit a connection
  2. enp0s3(一個しかないはず) > Edit
  3. Automatically connect をTrueにする(SpaceでOn/Off切り替えができる)
  4. Ok押して、Quitする。

YumのUpdate

yumのUpdateが行えたら、Networkに接続できてます。

yum -y update

Centさんが頑張ってくれます。長いので気長に待ちましょう...

とりあえずこれで、仮想環境の作成ができました。
次は、Apacheのインストールにまいりましょう。

LAMP構築: ApacheのInstallataion

ではではApacheをインストールしていきたいと思います。
Apacheのインストールは簡単ですが、SelinuxやFirewallなどに躓くことがあります。
できるだけ楽してやっていきましょう

Apacheのインストール

# apacheのインストール
yum -y install httpd
# apache serverの起動を永続化
systemctl enable httpd

これだけです。簡単ですね。
つぎが最初のころにはまる問題点だと思います。

Security関係

初期状態だとApacheServerを起動してもアクセスできないので、
設定を行っていきます。

firewallにhttpserviceを追加

ファイヤ―ウォールさんが http の接続をはじいちゃいますので、
http をはじかないように設定しましょう。

firewall-cmd --zone=public --permanent --add-service http

Sellinuxの無効化

本番環境では無効にしてはいけないのですが開発環境なので、無効にするのが楽なので無効にしてしまいます。

vi/etc/selinux/config 編集しましょう。
viはLinuxのエディターです。
i を押すと編集モードに、esc でコマンドモードになります。
編集が終わったらコマンドモードで :wp と入力し保存しましょう

vi /etc/selinux/config
/etc/selinux/config
SELINUX=disabled

では設定の反映のため再起動します。

reboot

Chromeで表示

ではChromeでちゃんとアクセスできるか確認しましょう。

Statusの確認

再起動がおわればそれぞれのStatusを確認しましょう

getenforce
service httpd status
  • getenforce
    • Disabled と表示されればOKです
  • service httpd status
    • Active: active (running) と表示があればOKです。

サイトにアクセス

では実際にWebサイトにアクセスしましょう。

まず ipaddress を確認します。

ip -a

enp0s3: のsectionにある、これっぽいなーってやつがadressです。(最後が255とかやないやつ)
例: 192.168.1.100

そのアドレスをChromeのurlに打ち込みましょう。

Testing 123... 

と表示されれば接続できてますねー。

表示内容の編集

apacheの初期設定では、/var/html/ がserverのルートDirectoryです。
そこの index.html を最初に参照します。
実際にindex.htmlを作成して、サイトの表示が変わるか試してみましょう。

echo "Hello World" > /var/www/html/index.html

これで /var/www/html/index.htmlHello World と書き込まれました。

ChromeをReloadして

Hello World 

と表示されれば成功です。

以上でApacheのInstallationが完了しました。

次はPHPのInstallationに進みましょう!

LAMP構築: PhpのInstallation

ではではPHP7をインストールしていきたいと思います。

Php7のインストール

デフォルトではyumにphp7が入ってないみたいなので、
yumでインストールできるようにRepositoryを追加してから。
PhpとPhpの基本Libralyをインストールしていきます。

# install php7 repo at yum repository.
yum -y install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

#install php7
yum install -y --enablerepo=remi,remi-php74 php php-gd php-pdo php-mbstring php-xml

インストールができたらApacheを再起動します。

service httpd restart

動作確認

では、実際にPhpが動くか確認しましょう。
/var/www/html/ に php_info.php を追加してChromeで表示してみます。

echo "<?php phpinfo();" > /var/www/html/php_info.php

ではChromeでアクセスしてみましょう。
URLに [ipadress]/php_info.php でアクセスできます。
例: 192.168.1.100/php_info.php

Phpの情報がずらーと表示されればOKです。

これでphpもインストールすることができました!

次はmysqlですね。

LAMP構築: MySqlのInstallation

ではではMySql8をインストールしていきたいと思います。
個人的には最難関。間違ってMysql5をインストールしてからMysql8に戻すとかする時に、ちょっとつかれる...
ここらへんで VirtualBoxのSnapshot に保存とかしとくといつでも戻れるのでチャレンジしやすいかもです。

MySql8のインストール

デフォルトではyumにmysqlが入ってないみたいなので、
yumでインストールできるようにRepositoryを追加してから,
MySql8をインストールしていきます。

最新のMySqlのRepositoryを確認しましょう
/mysql80-community-release-el7-3.noarch.rpm の部分を最新のに合わせてください。

# add mysql-community-server repo at yum repository
yum -y install http://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
# install mysql server
yum -y install mysql-community-server

Centさんがめちゃくちゃ頑張ってくれます。
長いので、猫と戯れるなりして気長に待ちましょう...

MySqlの起動

では実際に起動しましょう

# mysqlの起動永続化
systemctl enable mysqld
# mysqlの起動
systemctl start mysqld
# statusの確認
systemctl status mysqld

これで Active: active (running) になっていればOKです。

MySqlの初期設定

初期パスワード

まずrootユーザーが作成されているので、rootユーザーの初期パスワードを入手しましょう

cat /var/log/mysqld.log | grep root

A temporary password is generated for root@localhost: xxxxxxxxx
xxxxxxxxxx の部分が初期パスワードです。

基本はこれで出てくるはずなんですがもしなんか出てこないとなったらここを参照してください
参照先の my.cnf/etc/my.cnf のことです。

自動設定

では初期設定を行います。
mysql_secure_installation を使用して設定します。

mysql_secure_installation
  1. パスワードを聞かれるのでゲットした初期パスワードを入力しましょう。
  2. 新しいパスワードを設定してください。
  3. それ以外はすべてEnterを押していけばOKです。

パスワード認証方式の変更

Mysql8のパスワード認証方式にPHPが対応していないので対応している認証方式に変更します。

/etc/my.cnf
[mysqld]
default-authentication-plugin=mysql_native_password

すべての設定が完了したらMySqlを再起動しましょう

systemctl restart mysqld

MySqlにアクセス

ではrootユーザでアクセスしてみましょう。
下記のコマンドを実行してパスワードを聞かれるの入力してください。

mysql -u root -p

# アクセスできるとコマンドラインの最初に mysql>と表示される
# databaseの一覧を表示
mysql>show databases;

# できたらquitしましょう
mysql> quit

これでMysqlのInstallationが完了しました。

まとめ

以上LAMPの環境構築でした。
LAMPの環境構築は始めてやるとはまりまくりますが、黒い画面になれるためにも一度一からやってみると勉強になりますよね。

仮想環境はめちゃくちゃ便利なのでぜひ活用していきたいと思います。
なんか変になったら消せばいいし、SnapShot機能もあるので戻せますし。

次は復習がてらにPhpの自作WebFrameworkを作ろかと思います。
ではその時に会いましょう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【ActiveRecord】タブ区切りtsvをデータベーステーブルに登録する

概要

アウトプット用に、学習した内容を紹介していきます。
本日はActiveRecordを用いて、タブ区切りtsvファイルのデータをローカルデータベースにあるテーブルに登録してみます。

環境

Mac OS Mojave 10.14.6
Ruby 2.5.3
MySQL 5.7.28
ActiveRecord 6.0.1

テーブル

以下のタブ区切りtsvで保存された表を、ActiveRecordでローカルデータベース内のテーブルに保存する事を考えます。

posts.txt
user_id content
1       Hello
1       World
2       I'm Paul.
4       ?
5       ?

最終的に以下の形でDBに登録されて欲しいです。

postsテーブル

id user_id content
1 1 Hello
2 1 World
3 2 I'm Paul.
4 4 ?
5 5 ?

登録の流れ

それではまずtrainingというデータベースにpostsテーブルを作成します。
use training;でデータベースを選択しておきます。
また登録データに絵文字があるので、ALTER DATABASE training CHARACTER SET utf8mb4;などであらかじめ文字コードを変更しておきましょう。

postsテーブルを作成するのは以下のコードで作成します。

mysql> create table posts
    -> (id int auto_increment not null primary key,user_id int,content text);
出力
Query OK, 0 rows affected (0.01 sec)

idをauto_increment(自動的に番号を割り当て)のNULLを許さない主キーに設定し、user_idをint型、contentをtext型に設定します。

念の為テーブルを以下のコマンドで確認しておきます。

mysql> show columns from posts;
出力
+---------+---------+------+-----+---------+----------------+
| Field   | Type    | Null | Key | Default | Extra          |
+---------+---------+------+-----+---------+----------------+
| id      | int(11) | NO   | PRI | NULL    | auto_increment |
| user_id | int(11) | YES  |     | NULL    |                |
| content | text    | YES  |     | NULL    |                |
+---------+---------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> select * from posts;
出力
Empty set (0.00 sec)

無事設定したカラムで空のテーブルが作成されています。

それではここに、ActiveRecordを用いて先ほどのtsvデータを登録してみましょう。

regist_to_posts.rb
require 'active_record'
FILE_PATH = './posts.txt'

# DB接続
ActiveRecord::Base.establish_connection(
  adapter: 'mysql2',
  host: 'localhost',
  username: 'root',
  password: 'password',
  database: 'training',
  encoding: 'utf8mb4'
)

# Postクラスーpostsテーブルの対応
class Post < ActiveRecord::Base
end

# posts.txtを開く
file = File.open(FILE_PATH)
# 一行目はカラム名なので飛ばす
file.readline
# 一行ずつpostsに追加
file.each do |line|
  post = line.chomp.split("\t")
  Post.create(
    user_id: post[0],
    content: post[1]
  )
end

#DB接続の部分が、DBに接続するための呪文です。

そこから下でActiveRecord::Baseクラスを継承したPostクラスを用意しています。これでActiveRecord::Baseを継承したPostのクラスメソッドを通じてpostsテーブルへアクセスできるようになります。命名規則に従っているため、postsというテーブル名がコードに出てくることなくpostsテーブルへのレコードが登録できます。

そこから下は、postsテーブルにデータを追加していくコードです。
ちなみにrequire 'CSV'しておくと、

table = CSV.table(FILE_PATH, col_sep: "\t")
table.each do |line|
  Post.create(line.to_hash)
end

といったスッキリしたコードで書くことができます。

それでは実行してみましょう。

$ ruby regist_to_posts.rb
出力

ターミナルには何も出力されませんが、テーブルには書き込まれています。
コード中にActiveRecord::Base.logger = Logger.new(STDERR)を記述しておくとログが見れるのでおすすめです。

本当に登録できているのかテーブルを確認しに行きます。

mysql> select * from posts;
出力
+----+---------+-----------+
| id | user_id | content   |
+----+---------+-----------+
|  1 |       1 | Hello     |
|  2 |       1 | World     |
|  3 |       2 | I'm Paul. |
|  4 |       4 | ?          |
|  5 |       5 | ?          |
+----+---------+-----------+
5 rows in set (0.00 sec)

無事に登録できたようです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MySQLのreplace便利

httpをhttpsに変換する。
MySQLの replace を使えば便利。

update pages set url = replace(url, 'http://', 'https://');
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EmbulkでMySQLのdate型をBigQueryに送る。2019-11-12

概要

EmbulkでMySQLのデータをBigQueryに送ります。
そのときMySQLの date型 をBigQueryの date型 として気楽に送るとエラーになります。
その対応などを書きます。

Embulk

Embulkの利用、の前の準備 の通り

MySQL 環境

% cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.3 LTS"
% sudo apt-get install mysql-server-5.7 mysql-client-5.7
% mysqld --version
mysqld  Ver 5.7.27-0ubuntu0.18.04.1 for Linux on x86_64 ((Ubuntu))

検証に使うテーブル

CREATE TABLE `example_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `date` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

てきとうに数件データを入れた。

insert into example_table
(`date`)
values
('2018-03-27'),
('2018-04-30'),
('2018-05-01'),
('2018-12-31'),
('2019-01-01'),
('2019-03-27'),
('2019-04-30'),
('2019-05-01'),
('2019-12-31'),
('2020-01-01');
mysql> select * from example_table;
+----+------------+
| id | date       |
+----+------------+
|  1 | 2018-03-27 |
|  2 | 2018-04-30 |
|  3 | 2018-05-01 |
|  4 | 2018-12-31 |
|  5 | 2019-01-01 |
|  6 | 2019-03-27 |
|  7 | 2019-04-30 |
|  8 | 2019-05-01 |
|  9 | 2019-12-31 |
| 10 | 2020-01-01 |
+----+------------+

Embulk: MySQL -> BigQueryの設定周り

必要なプラグインのインストール

% embulk gem install embulk-input-mysql
% embulk gem install embulk-output-bigquery

とりあえずの設定ファイル

他の記事でも解説されているので詳細な内容については割愛します。

ポイント

  • MySQLの設定ではカラムの指定のみ
  • BigQueryのschema設定で、MySQLの date型 をBigQueryの方でも date型 で指定
config.yml
in:
  type: mysql
  host: localhost
  user: USER_NAME
  password: PASSWORD
  database: DATABASE_NAME
  table: example_table
  select: id, date
out:
  type: bigquery
  auth_method: json_key
  json_keyfile: JSON_KEY
  path_prefix: /tmp/
  file_ext: .csv.gz
  source_format: CSV
  project: PROJECT
  auto_create_dataset: true
  dataset: example_dataset
  auto_create_table: true
  table: bq_example_table
  schema_file: ./schema.json
  formatter: {type: csv, charset: UTF-8, delimiter: ',', header_line: false}
  encoders:
  - {type: gzip}
scheme.json
[
  {"name": "id", "type": "INTEGER", "mode": "required"},
  {"name": "date", "type": "DATE", "mode": "required"}
]

本題のDate型の動きを検証

上述の「とりあえずの設定ファイル」で実行してみる

エラーで失敗します。

エラーの原因をログから拾うと以下の内容

"Error while reading data, error message: Could not parse '2018-03-27 00:00:00.000000 +00:00' as date for field date (position 1) starting at location 0"

BigQueryの date型 のカラムに 2018-03-27 00:00:00.000000 +00:00 を入れようとして時間も付いているのでエラーになった様子。

ちょっと設定を変えねばなりません。

BigQueryのdateカラムをSTRINGにしちゃう

scheme.json
 [
   {"name": "id",   "type": "INTEGER", "mode": "required"},
-  {"name": "date", "type": "DATE", "mode": "required"}
+  {"name": "date", "type": "STRING", "mode": "required"}
 ]

とすると、いちおうエラーなくインサートされます。

スクリーンショット 2019-11-12 11.42.29.png

ただしBigQueryには 2018-03-27 00:00:00.000000 +00:00 という文字列として入ります。
以下の通り、一手間加えれば期待通りに動くもののちょっとなんとかしたい気持ちになります。

  • cast
    • cast(substr(date, 0, 10) as DATE)
  • 範囲指定
    • where cast(substr(date, 0, 10) as DATE) between '2018-01-01' and '2018-12-31'

MySQLの結果を加工

MySQLの結果をそのまま渡すと時間もくっつくみたいなので、ちょっと加工します。

scheme.jsondate型 の状態。)

config.yml
   table: example_table
   select: id, date
+  column_options:
+    date: {type: string, timestamp_format: "%Y-%m-%d", timezone: "Asia/Tokyo"}
 out:
   type: bigquery

dateを YYYY-MM-DD 形式にしてあげます。

参考: https://blog.adachin.me/archives/9196

これでBigQueryには date型 で、値は 2018-03-27 のような値で良い感じにインサートされました。

スクリーンショット 2019-11-12 12.06.15.png

追記: output-bigquery側で加工

考え方としては「MySQLの結果を加工」と同様です。
output-bigquery側でも設定できるようになったようです。(詳細はコメント欄参照)

「MySQLの結果を加工」と同様なので設定例だけ記載します。outの方に設定を追加します。

config.yml
   formatter: {type: csv, charset: UTF-8, delimiter: ',', header_line: false}
   encoders:
   - {type: gzip}
+  column_options:
+  - {name: date, type: DATE, timezone: "Asia/Tokyo"}

STRING型 -> DATE型 で出そうな影響

とりあえずの逃げで「BigQueryのdateカラムをSTRINGにしちゃう」で運用していたので、BigQuery側を date型 にすることで出そうな影響について考えます。

  • 範囲指定
    • むしろこれまでより楽になるので特に影響なさそう
  • タイムゾーン
  • <それ以外>
    • <何かあれば追記>

まとめ

Embulkで良い感じにMySQLの date型 をBigQueryの date型 として送れました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Mysqlに入ってからAccess deniedやgrantないよが出たら

前提

・macユーザーでmysql内でアクセス拒否された、no grantが出て解決策見つからないという方向けの参考メモ。
・とはいえ、他にも似た記事があるので自分のメモ用という意味合いが強いです。

やり方

1、exitします。
2、以下のコマンドを打ちます。

mysqld_safe --skip-grant-tables &

3、rootユーザーで入ります。

mysql -u root

4、
https://qiita.com/yamateion/items/5509484aaf1a02e9cc57
にある文を打ち込みます...が、権限を全て付与したいときは以下のように打ち込みます。

create user 'user'@'localhost' identified by 'password';
grant all privileges on *.* to 'user'@'localhost';

参考記事との違いは、2文目で.としていることです。

追記

2番のコマンドを打ったあと、mysqlのプロセスをkillしておかないと、
mysqld_safe A mysqld process already exists
というエラーが出ます。
このエラーが存在していると、2回目以降mysql -uroot で入れなくなります。
よって、

ps aux| grep mysqld

コマンドをうってプロセスID一覧を取得し、一つ一つkillすると良いです。

参考文献

https://qiita.com/yamateion/items/5509484aaf1a02e9cc57
http://www.goofoo.jp/2011/11/1457

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHPでページネーションを使って投稿一覧機能【初心者】

WEBページを作っていると記事を一覧表示させる事が多々あると思います。
その際に下の方までずーっとスクロールして見る長いページを作るのではなく、ページングして綺麗に見せようというのが今回の内容です。

キャプチャ.PNG

↑こういうやつです。

投稿の取得

投稿の取得

まずは投稿を取得していきます。
ここではテーブル名bbs_threadから投稿内容(thread)と投稿日(created)を取得しています。

<?php
// ドライバ呼び出しを使用して MySQL データベースに接続
$dsn = 'mysql:dbname=データベース名;charset=utf8mb4';//データベース名
$user = 'root';//設定していればそれを使う
$password = 'root';//設定していればそれを使う

try {
    $db = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
    echo "DB接続エラー: " . $e->getMessage() . "\n";
    exit();
}
$posts = $db->query('SELECT thread, created FROM bbs_thread ORDER BY created DESC');

function h($value){
    return htmlspecialchars($value,ENT_QUOTES);
}

投稿された内容を表示するので、htmlspecialcharsもファンクション化しておきましょう。

次にHTMLを書いていきます。
foreachを使って取得した内容を表示します。

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>

<body>
    <?php
foreach($posts as $post):
?>
    <h3><?php echo h($post['thread']); ?></h3>
    <p><?php echo h($post['created']); ?></p>
    <?php
endforeach;
?>
</body>

</html>

これで以下のように取得できたかと思います。
キャプチャ.PNG

ページングするように変更

1ページあたり5件表示するように書き換えていきます。

//URLパラメータで指定された値を$pageに代入
$page = $_REQUEST['page'];
//空だった場合は1とする
if($page == ''){
    $page = 1 ;
}
//最小のページ数を1とする
$page = max($page,1);

//最終ページの取得
//データ件数を取得してcntと名付ける
$counts = $db->query('SELECT COUNT(*) AS cnt FROM bbs_thread');
$cnt = $counts->fetch();
//取得した件数を1ページで表示したい件数で割り、ceil関数で小数点以下を切り捨てる
$maxPage = ceil($cnt['cnt']/5);
//最大のページ数以上を表示させないようにする
$page = min($page,$maxPage);

$start = ($page -1)*5;

//設定した値を使用するのでprepareを使用して値を取得
$posts = $db->prepare('SELECT thread, created FROM bbs_thread ORDER BY created DESC LIMIT ?, 5');
$posts->bindParam(1, $start, PDO::PARAM_INT);
$posts->execute();

HTMLではページが変わるように付け加えましょう。

<div>
        <ul class="pagination">
            <li class="page-item">
                <a class="page-link" href="test.php?page=<?php print($page - 1); ?>">«</a>
            </li>
            <?php
                for($i=1;$i<=$maxPage;$i++):
                ?>
            <?php
                if($_REQUEST['page'] == $i):
                ?>
            <li class="page-item active">
                <a class="page-link" href="test.php?page=<?php echo $i ;?>"><?php echo $i ?></a>
            </li>
            <?php
              else :
                ?>
            <li class="page-item ">
                <a class="page-link" href="test.php?page=<?php echo $i ;?>"><?php echo $i ?></a>
            </li>
            <?php
              endif;
              ?>
            <?php
              endfor;
              ?>
            <li class="page-item">
                <a class="page-link" href="test.php?page=<?php print($page + 1); ?>">»</a>
            </li>
        </ul>
    </div>

最後にCSSで見た目を整えて、

.pagination{
        list-style: none;
        display:flex;
    }
    .page-item{
        margin:5px;
    }

最終的にはこうなりました。
キャプチャ.PNG

立派にページングできたのではないでしょうか。

最後に

コードに細かくコメントアウトしていたので説明を省略したところも多かったですが、ページネーションの方法を知らない人がこの投稿を読んで、出来るようになれたらいいなと思います。
読んでいただきありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む