PHPのPDOの使い方を分かりやすく解説する
PHPでデータベースを操作するのにPDOを使うことが多いが、今回のそのPDOの使い方について解説していく。
そもそもPDOって何?
PDOとはPHP Data Objectsの略で、データベースへの接続、使用を簡単にしてくれるもの。
通常データベースを使用するためには、MySQLやSQLite3などのデータベースの種類によって関数やライブラリを使う必要があるが、PDOであればどのデータベースでも同じような記述で動かすことができる。
PDOは、PHP5.1以降で使うことができ、PHP5.0であればPECL 拡張モジュールとして提供されている。
PDOでデータベースに接続する
PDOでデータベースに接続するためには、new
を使ってPDOインスタンスを作成すれば良い。
例えば、以下のような感じで。
<?php
$host = '127.0.0.1';
$db = 'sample_db';
$user = 'root';
$pass = 'password';
$charset = 'utf8';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
try {
$pdo = new PDO($dsn, $user, $pass);
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int) $e->getCode());
}
上記のコードの例ではMySQLを使っている。
また、データベース接続をする際にtry
を使って例外処理を行なっている。これは万が一データベースの設定が適切でなかったり、データベース側に何かしらのトラブルがあった場合を考慮するために行なっている。
PDOのオプションについて
上記のコードでもPDOでデータベースの接続ができるが、よりPDOを使いやすくするためにオプションを設定すると良い。
オプションを使うためのメソッドとしてsetAttribute
があるので、これを使う。
public PDO::setAttribute ( int $attribute , mixed $value ) : bool
setAttribute
は、第1引数にオプション名、第2引数にオプションの値を入れる。具体的には以下のように使う。
try {
$pdo = new PDO($dsn, $user, $pass);
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int) $e->getCode());
}
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
上記の例ではsetAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
としているが、これはPDOでの例外エラーを詳細にするためのオプションで、デバッグ時に役立つオプションとなる。
setAttribute
は便利なメソッドだが、指定したいオプションが増えてくると何回も書かないと行けなくなり面倒だ。
もし、オプションが複数になる場合は、$options
変数みたいな物を用意して、その$options
変数をPDOインスタンス生成時に、第4引数として渡してやると良い。
具体的には以下のような感じになる。
<?php
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int) $e->getCode());
}
参考:PHP: PDO::setAttribute - Manual
PDOで良く使うオプション
PDOでは、以下の3つがオプションとして使われることが多い。
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
PDOの例外エラーを詳細にしてくれるオプション。
PDOのエラー文はデータベース接続時は詳細のエラーを表示してくれるが、select
文などのSQL実行時にエラーが出た場合は、非常にそっけないエラー文を表示する。
Fatal error: Uncaught Error: Call to a member function execute() on bool in /Users/unknown/pdo.php:26
これだと、execute()
がエラーになったことが分かるが、具体的に何が悪くてエラーになったかが分からない。
そこでPDO::ERRMODE_EXCEPTION
のオプションをつけると、以下のようにエラー文が変わる。
Fatal error: Uncaught PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'oreore.users' doesn't exist in /Users/unknown/pdo.php:26
上記のエラーにはBase table or view not found: 1146 Table 'oreore.users' doesn't exist in
と書かれており、存在しないテーブルにアクセスしようとしてエラーが出た、と言うことが一発で分かるようになる。
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
このオプションを使えば、select
文やwhere
句などの結果を連想配列として返してくれるようになる。
デフォルトでは、SQLの結果は要素の番号が0,1,2と言う普通の配列として返ってくるが、このオプションをつけることで、以下のように値を返してくれるようになる。
{
"name" => "tarou",
"age" => 14
}
PDOでSQLを実行する
PDOでSQLを実行するためにはprepare
メソッドでSQL文をセットして、execute
メソッドでSQLを実行する。
try {
$pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int) $e->getCode());
}
$sql = "select * from samples";
$stmt = $pdo->prepare($sql);
$stmt->execute();
prepare
メソッドでは、PDOStatementオブジェクトを生成しており、execute
メソッドを使うことでPDOStatementオブジェクト内でSQLの結果を保持する、と言う仕組みになっている。
なので、よく初学者が
<?php
$results = $stmt->execute();
上記のコードのように書いて$results
変数にSQLの結果があると思い込みがちだが、execute
の戻り値はtrue falseのどちらかであり、実際のSQLの結果はPDOStatementオブジェクト(ここでは$stmt
)が保持している。
参考:PHP: PDOStatement::execute - Manual
では、どのようにSQLの結果を出すかと言うと、fetch
またはfetchAll
を使うと良い。
<?php
$stmt->execute();
while($row = $stmt->fetch()){
// 処理
}
上記のコードの$row
には、SQLの結果の一行が配列、または連想配列として取り出される。まとめて全ての結果を取り出したい場合はfetchAll
を使うと良い。