前回、ターミナルからコマンドを使ってMySQLにログインしました。
この記事ですね▼
実はPHPのプログラムで自動的にMySQLに接続することができます。
先に、今回最終的に書くコードを載せておきます。
これが書けるようになります↓
try {
// PDOインスタンスの作成
$pdo = new PDO(DSN, DB_USERNAME, DB_PASSWORD);
// エラー処理方法の設定
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $pdo;
} catch(PDOException $e) {
echo 'Error: ' . $e->getMessage();
die();
}
見慣れない記述がだいぶ多いですが、大丈夫です!
全て解説してあるので確認していきましょう!
DB接続の流れを確認
まず、今までは接続のために、ターミナルに以下を打ち込みましたよね。
/Applications/MAMP/Library/bin/mysql -u root -p
そして、次にパスワードが求められるので「root」と打つことで接続をしました。
日本語で言うと、
- MySQLというデータベースに
- ユーザ名「root」
- パスワード「root」
この3つの情報で接続する。という意味になります。
プログラミングのコードで接続するときも同じように、この3つの情報が必要になります。
DB接続をするコード
最初に結論を書きます。
実はこれを書くだけでDB接続は完了します。
new PDO(DB接続に必要な情報, ユーザ名, パスワード);
全部で3つある引数には、DB接続に必要な3つの情報を指定する必要があります。
3つの引数について
「DB接続に必要な情報」とはDBの種類と接続するDB名の2つです。
➡︎ 種類は「MySQL」ですよね。DB名は、前回作成した「test_db」にしておきましょう。
「ユーザ名」
➡︎ 「root」ですよね。
「パスワード」
➡︎ 「root」ですよね。
このような接続のための情報は定数で書いておくのが一般的です。
コードで書くと次のようになります。
<?php
// DB名
define('DB_DATABASE', 'test_db');
// MySQLのユーザー名
define('DB_USERNAME', 'root');
// MySQLのログインパスワード
define('DB_PASSWORD', 'root');
// DSN
define('DSN', 'mysql:host=localhost;charset=utf8;dbname='.DB_DATABASE);
?>
定数defineの構造について
define(‘DB_DATABASE’, ‘test_db’); は以下と同じようなイメージです。
↓
$DB_DATABASE = ‘test_db’;
難しいのは、コメントアウトでDSNとある最後の行だと思います。
「DSN」という定数名に何やら長い値を代入していますね。
分解してみると、
- mysql:host=localhost;
➡︎ 使うDBの種類は「MySQL」で「localhost」を使いますよ。 - charset=utf8;
➡︎ 文字コードは「UTF-8」ですよ。(これで文字化けを防げる) - dbname=’.DB_DATABASE
➡︎ 使用するDB名はすぐ上で定義した定数「DB_DATABASE」を指定
つまり、
DBの種類はMySQLでlocalhostです。
文字化けしないように文字コードUTF-8を指定して、
DB名はtest_dbを指定
という情報を丸ごと「DSN」という変数に代入しているということになります。
「DSN」、「DB_USERNAME」、「DB_PASSWORD」というDB接続に必要な3つの情報は揃ったので、
引数に使用するとこのような形になります。
// new PDO(DB接続に必要な情報, ユーザ名, パスワード);
new PDO(DSN, DB_USERNAME, DB_PASSWORD);
なんでこれだけで接続できるの?
というか「new PDO」って何?
と思うかもしれませんが、
これはPHPが元々用意している便利機能があってそれを使用しているだけです。
「new PDO」と書いて3つの引数(DSN、DB_USERNAME、DB_PASSWORD)を指定すると、
その情報をもとにDB接続を自動でやってくれます。便利ですね。
例外処理を入れておく
通常、プログラム実行時に何らかの不具合があったときは処理が停止してしまいます。
しかし、運用中のアプリやシステムが異常終了という形で止まってしまうのは良くないです。
そこで、エラーが起きた時の処理を決めておくことで異常終了させないようにします。
例外処理の基本系
例外が起きそうな箇所を「try」と「catch」で囲みます。
そして、本当に例外が起きた時の処理を「catch」の後に記述します。
「PDOException $e」は例外処理のオプションのようなものとして、とりあえず書いておきます。
コードで書くとこんな形です。
try {
// 例外が起きる可能性がある処理
} catch(PDOException $e) {
// 本当に例外が起きた時の処理
die();
}
「例外が起きる可能性がある処理」とは、今回だと「DBに接続をする処理」になります。
え?なんで「例外が起きそうな場所」が「DB接続のタイミング」なの?
今までにデータベースに接続しようとしたときに、
- データベース名を間違えた
- パスワードを間違えた
- MAMP/XAMPPを起動していなかった
これらの理由で、上手く接続できなかった事ありませんか?
そうなんです。データベースに接続する時って、エラーが起きやすいんです。
なので、その部分は丸ごと「try」で囲っておこう!ということになります。
「try」の中身はこんな感じになります。
try {
// PDOインスタンスの作成
$pdo = new PDO(DSN, DB_USERNAME, DB_PASSWORD);
} catch(PDOException $e) {
// 本当に例外が起きた時の処理
die();
}
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
「$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);」
ちょっと長いですがこれを記述すると、エラーを見やすく表示してくれるようになります。
↑オプションのようなもので「このように書くもの」と決まっているので、そのまま記述します。
ついでに、「return $pdo; 」
で、呼び出しもとに接続の結果を返しておきます。
↑詳しくは「戻り値について」の記事をご覧ください。
今のところこんな感じのコードになります。
try {
// PDOインスタンスの作成
$pdo = new PDO(DSN, DB_USERNAME, DB_PASSWORD);
// エラーの表示方法の設定
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $pdo;
} catch(PDOException $e) {
// 本当に例外が起きた時の処理
die();
}
$e->getMessage()
続いて「本当に例外が起きた時の処理」とは、具体的に何をするのかというと、
「エラー内容を出力する」というものになります。
$e->getMessage()
と書くと、その時発生したエラー内容を生成してくれます。
あとは、echo で画面表示すれば良いだけですね。
最後の「die();」は、
例外処理を終了するという意味です。
最終的には、このような形になります。
try {
// PDOインスタンスの作成
$pdo = new PDO(DSN, DB_USERNAME, DB_PASSWORD);
// エラーの表示方法の設定
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $pdo;
} catch(PDOException $e) {
echo 'Error: ' . $e->getMessage();
die();
}
DBのデータを取得してみよう
DB接続はこの記述で完了しています。
これからDBに登録されているこの情報を取得してきましょう。
【2-2】 MySQLにログインしてみようで作成したデータですね。
まずは、MAMP/XAMPPを起動しておいてください。
MySQLにログインする必要は無いですが、MAMP/XAMPPは起動しておかないと動かないので気をつけてください。
SELECT文でデータを取得!
DBからデータを取得するためにはSELECT文を使用します。
SELECT * FROM users WHERE name = "テスト太郎"
必要なSELECT文はこのようになります。
しかし、これをコードに書く場合はどうなるのでしょうか?
答えはPHPの便利機能「prepare」を使います。
ちょっと小難しい話になりますが、
prepareはPDOクラスのメソッドで、SQLをPHPが認識できる形に変換してくれます。
(PDOクラスというのは、PHPにもともと準備されているクラスです)
「new PDO」した時に入れ直しておいた変数「$pdo」経由で以下のように使用します。
$pdo->prepare();
引数の中には、SQLを入れれば良いので以下のような形で使用できます。
$pdo->prepare("SELECT * FROM users WHERE name = 'テスト太郎'");
ちなみに、
今回のSQLは短いので直接引数の中に入れても大丈夫ですが、
すごく長い場合は見にくくなってしまいます。
そのため、一般的にはSQLを変数に入れて使うようにします。
$sql = "SELECT * FROM users WHERE name = 'テスト太郎'";
$pdo->prepare($sql);
さらにまた難しい話になりますが、prepareメソッドを使うと、
「ステートメントオブジェクト」と呼ばれるもので値が返ってきます。
(ステートメントオブジェクトが何かは気にしなくて大丈夫です)
そのため、ステートメントの略で「$stmt」という変数名でその値を受け取ってあげましょう。
$stmt = prepare("SELECT * FROM users WHERE name = 'テスト太郎'");
最後に「$stmt->execute();」とすることで、SQLを実行することができます。
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = 'テスト太郎'");
$stmt->execute();
取得した結果を画面表示してみよう
ここまでの作業で、変数$stmtにDBから取得した結果が全て入っていることになります。
この後、$stmtをループで回しながら一件ずつ画面に出力するということを行います。
今回は、データが一件しかないのでループする必要はありませんが、
今後のためにこの書き方に慣れておいた方が良いと思います。
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row['id']. '、' . $row['name'] . '、' . $row['password'];
}
「$stmt->fetch(PDO::FETCH_ASSOC)」
と書くことで、カラム名を取得できます。
さらにその結果が、変数$rowの中に入ります。
あとは、
- $rowの中に入っているid ➡︎ $row[‘id’]
- $orwの中に入っているname ➡︎ $row[‘name’]
- $rowの中に入っているpassword ➡︎ $row[‘password’]
この形をechoすれば全件表示ができます。
ここまでの全体のコードはこのような形になります。
<?php
// DB名
define('DB_DATABASE', 'test_db');
// MySQLのユーザー名
define('DB_USERNAME', 'root');
// MySQLのログインパスワード
define('DB_PASSWORD', 'root');
// DSN
define('DSN', 'mysql:host=localhost;charset=utf8;dbname='.DB_DATABASE);
try {
// PDOインスタンスの作成
$pdo = new PDO(DSN, DB_USERNAME, DB_PASSWORD);
// エラー処理方法の設定
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo 'Error: ' . $e->getMessage();
die();
}
$sql = "SELECT * FROM users WHERE name = 'テスト太郎'";
$stmt = $pdo->prepare($sql);
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row['id']. '、' . $row['name'] . '、' . $row['password'];
}
?>
まとめ
今回は、見やすさ重視のために一つのファイルに書いてありますが、
一般的にはDB接続のコードは別のファイルに記述しておいて、それを読み込む形で使用します。
また、PDO、stmt、prepareなど、突然難しそうなものが出てきましたが、
ほとんどがPHPが元から用意している便利な機能を使っているだけになります。
気になる部分は「PHP prepare」などで一つずつ検索してみるとわかりやすいかと思います。
- 実際には「new PDO(DB接続に必要な情報, ユーザ名, パスワード);」だけでDB接続は完了
- PDO、stmt、prepareなどはPHPの標準搭載されている便利機能を使っているイメージ
- 動作確認をするときは、MAMP/XAMPPが起動してある必要がある