PDOについて、自分で理解するために調べた内容をまとめただけの備忘録です。
よりよい方法や間違い等ございましたら、アドバイスいただけると光栄です。
#前提条件
下記条件を前提に話を進めます。
- PHPは
PHP 5.3.6
以上 - データベースは
MySQL
- 文字エンコードは
UTF-8
#PDOとは
「PHP Data Objects」の頭文字をとった名称です。
今まではデータベースの種類によって利用する関数を分けていました。
例えば、
MySQLへ接続する場合は「mysql_connect」関数で接続していましたし、
PostgreSQLの場合は「pg_connect」関数で接続していました。
データベースを固定している場合は問題がありませんが、
もし将来的に違うデータベースへの変更や移植もする場合には、
全て書き換えなくてはいけません。。。
しかし、PDOクラスを使用すれば、
どのデータベースを利用する場合でも同じ関数を使うことができますので、
もし将来データベースを変更することがあっても、
PDOクラスを作成する時に指定したパラメータだけを変更するばいいことになります。
(まあ、データベースによって若干の差異はあるそうですが。。。)
まずはPDOクラスを使ってデータベースに接続する方法を見ていきましょう。
#PDOでDBに接続
MySQLに接続するときは、下記のように記述します。(PHP5.3.6以降)
$dsn = 'mysql:host={サーバー名};dbname={データベース名};charset={文字エンコード}';
$db_user = '{ユーザー名}';
$db_pass = '{パスワード}';
$driver_options = [
変更したい属性 => 値,
変更したい属性 => 値,
];
try {
$pdo = new PDO($dsn, $db_user, $db_pass, $driver_options);
} catch (PDOException $e) {
exit('データベース接続失敗。' . $e->getMessage());
}
引数中身を詳しく見ていきましょう。
$dsn
データソース名(Data Source Name)。データベースに接続するために必要な情報が含まれます。
MySQLの基本的な書き方を例に挙げます。
mysql:host={サーバー名};dbname={データベース名};charset={文字エンコード}
- 頭にデータベースの種類を指定して
:
で区切る。 - 各項目は 項目名=値 とし、
;
で区切る。
指定する各項目について、詳しく見ていきましょう。
{サーバー名}
ホスト名(localhost
など)またはIPアドレス(127.0.0.1
など)を指定します。
一般的には
- Linux環境はホスト名推奨
- Windows環境はIPアドレス推奨
となっております。
{データベース名}
データベース名を指定します。
基本的には必須ですが、データベースを後で USE test
のようにSQL文で選択する場合、省略することができます。
{文字エンコード}
文字エンコードを指定します。
補足ですが、UTF-8
ではなく utf8
であることに注意してください。ハイフンは入りません。
また、PHP 5.3.5 以前の PDO では、ここで文字エンコードの指定が出来ません。
そのため、ドライバ固有の接続オプション(詳細については後述)での指定が必要になります。
詳しい方法などについては、こちらの記事にまとまっているので、おすすめです。
$db_user
DSN文字列のユーザー名。ルート権限でのデフォルト値は、root
です。
$db_pass
パスワード。ルート権限でのデフォルト値は、空白です。
$driver_options
接続時のオプションを連想配列で指定します。
それとは別に、PDOクラスをインスタンス化した後にオプションを設定することも可能です。
$dsn = 'mysql:host={サーバー名};dbname={データベース名};charset={文字エンコード}';
$db_user = '{ユーザー名}';
$db_pass = '{パスワード}';
$pdo = new PDO($dsn, $db_user, $db_pass);
$pdo->setAttribute(変更したい属性 , 値);
$pdo->setAttribute(変更したい属性 , 値);
オプションの中には、インスタンス化のときだけしか設定できないものがあります。
特に理由がなければ、インスタンス化するときに連想配列でオプションを設定するようにしましょう。
オプションとその値については、マニュアルにまとまっているのでおすすめです。
PDOでSQL文を実行
PDOでSQL文を実行する際には、下記2種類のメソッドが使えます。
- query
- prepare
次に、各メソッドについて詳細を見ていきましょう。
1. queryメソッド
SQL文を即時実行、1回しか使わないならqueryメソッドを使うといいです。
$stmt = $pdo->query("SELECT * FROM `user`");
返されるオブジェクトはPDOStatement
と呼ばれるオブジェクトで、$pdo
の内容とは別のものですので注意してください。
このオブジェクトはデータベースから引っ張ってきた情報をPHPで出力、つまりサイトの画面に表示したり、計算に使うために必要です。
2. prepareメソッド
queryメソッドは、パラメータに変数を使うことでより柔軟にすることもできます。
しかし、実はSQLを使いまわす用のメソッドもあります。それがprepareメソッドです。
使い方は2通りあります。
// パターン1:変数を?で代用する
$stmt = $dbh->prepare("SELECT * FROM `user` WHERE `user_name` = ? AND `age` = ?");
$stmt->execute(array('山田太郎', 22));
// パターン2:変数名の$をコロンに変える
$stmt = $dbh->prepare("SELECT * FROM `user` WHERE `user_name` = :user_name AND `age` = :age");
$stmt->bindValue(':user_name', '山田太郎');
$stmt->bindValue(':age', 22, PDO::PARAM_INT);
$stmt->execute();
prepare
はSQL文の準備をするメソッドで、excute
はそれを実行するメソッドです。
executeメソッドを実行したことで、queryメソッドを実行したことと同じになります。
尚、prepare
excute
も、PDOStatementオブジェクトが返されます。
データを出力
queryメソッドやprepareメソッドでSQL文を実行しただけでは、
PDOStatementオブジェクトに結果セット保持されているだけで、値としてはまだ使えません。
値を取得するには、fetch
やfetchAll
というメソッドを使用します。
// PDOクラスをインスタンス化
$pdo = new PDO(...);
// PDOStatementオブジェクトに結果セット保持
$sql = "SELECT * FROM `user`";
$stmt = $pdo->query($sql);
// 値を取得
$results = $stmt->fetchAll();
fetchメソッド や fetchAllメソッドは、引数にオプションを入れて、様々な形で出力することができます。
よく使われるオプションとその値については、こちらの記事にまとまっているのでおすすめです。