PHP Data Object

PHP Data Object

PDOのおさらい。

PDOとは?

PHP Data ObjectはPHP5.1以降から実装された抽象化ライブラリのことで、中身はC言語で書かれています。
PHP本体にバンドルされているためインストール作業等は不要です。

PDOはPEAR DBやMDB2のすべての機能をサポートしているわけではありません。
また、PHPはすべてのデータベース製品に対してアクセスをサポートしているはけではないです。

アクセス方法

データベース接続する場合、データソース名(DSN:Data Source Name)が必要となる
データベースサーバのアドレス、ユーザーID、パスワード、その他オプションを指定する。

$dsn = 'mysql:host=localhost;dbname=test';
$user = 'admin';
$pass = 'password';
$option = array(PDO::ATTR_PERSISTENT => true);
$db = new PDO($dsn,$user,$pass,$option);

切断する場合はオブジェクトを空にします

$db = null;

PDOによる属性

setAttribute()メソッドを使用することで属性の値を変更することが可能。
属性値は以下

PDO::ATTR_AUTOCOMMIT オートコミットの有効化無効化
PDO::ATTR_CLIENT_VERSION クライアントのバージョン
PDO::ATTR_DRIVER_NAME ドライバ名
PDO::ATTR_ERRMODE エラーモード
PDO::ATTR_ORACLE_NULLS 空文字をnullに変換
PDO::ATTR_PERSISTENT 持続的接続を要求
PDO::ATTR_SERVER_INFO サーバーの情報
PDO::ATTR_SERVER_VERSION サーバーのバージョン
PDO::ATTR_TIMEOUT データベースとの通信のタイムアウト値
//ドライバ名の出力
echo $db->getAttribute(PDO::ATTR_DRIVER_NAME);

PDOにおけるエラー処理

エラーモード

PDO::ATTR_ERRMODE属性を指定することで、エラーの報告をどのように表示するかを設定できる。

PDO::ERRMODE_SILENT エラーコードのみ設定
PDO::ERRMODE_WARNING E_WARNINGを発生
PDO::ERRMODE_EXCEPTION 例外を投げる
$db->getAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);


<h3>エラーメッセージ取得</h3>
エラーメッセージを取得するにはPDOExceptionクラスのgetMessageメソッドを使用する

try{
	$dsn = 'mysql:host=localhost;dbname=test';
	$user = 'admin';
	$pass = 'password';
	$option = array(PDO::ATTR_PERSISTENT => true);
	$db = new PDO($dsn,$user,$pass,$option);
	$db->getAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
	/*
		.
		.
		.
	*/
} catch (PDOException $e){
	echo $e->getMessage();
}

PDOによる実行処理

SQLの実行処理

exec SQL文を実行し作用した行数を返す
query SQL文を実行し結果セットをPDOStatmentオブジェクトとして返す
lastInsertId 最後に挿入された行のIDか指定されたシーケンスの値を返す

try{
	$dsn = 'mysql:host=localhost;dbname=test';
	$user = 'admin';
	$pass = 'password';
	$option = array(PDO::ATTR_PERSISTENT => true);
	$db = new PDO($dsn,$user,$pass,$option);
	$query = 'CREATE Table t (a Int)';
	$db->($query);
	$rows = $db->exec('INSERT INTO t (a) VALUES (1),(2),(3)');
	echo $rows;
	echo $db->lastInsertId();
	$rows = $db->exec('DELETE FROM t WHERE a = 1');
	echo $rows;
} catch (PDOException $e){
	echo $e->getMessage();
}

結果セットからデータを取得

PHPのマニュアルより参照
データの取得にはfetchを使用する

PDOStatement::fetch 結果セットから次の行を取得する
PDOStatement::fetchAll 全ての結果行を含む配列を返す
PDOStatement::fetchColumn 結果セットの次行から単一カラムを返す
PDOStatement::fetchObject 次の行を取得し、それをオブジェクトとして返す
PDOStatement::rowCount 直近の SQL ステートメントによって作用した行数を返す
PDOStatement::setFetchMode この文に対するデフォルトのフェッチモードを設定する
//オブジェクトとして取得
$stm->fetchAll(PDO::FETCH_CLASS);
//配列として取得
$stm->fetchAll(PDO::FETCH_ASSOC);

プリペアドステートメント

一度準備したSQL文を再利用するもの。
SQLを準備する時間を短縮して処理を高速化させるのに役立ちます。
PDOのprepareメソッドは指定されたSQL文を準備し、PDOStatementクラスのインスタンスを返す

try{
	$dsn = 'mysql:host=localhost;dbname=test';
	$user = '';
	$pass = '';
	$db = new PDO($dsn,$user,$pass);
	$stm = $db->prepare('SELECT * FROM t');
	$stm->execute();
} catch (PDOException $e){
	echo $e->getMessage();
}

プレースホルダ

プレースホルダを使用すると文字列としてSQLを組み立てるときなどに役立ちます。
変数にシングルクォートなどの記号が含まれるなどといった、文法的に不正なSQLが生成されるのを防ぐことができます。
SQLに埋め込む値を適切にエスケープしてくれます。

データベースやライブラリにより異なるが、疑問符プレースホルダ、名前付きプレースホルダなどがあります。
疑問符プレースホルダ

SELECT * FROM user_table WHERE id = ? AND PASSWORD = password(?)

名前付きプレースホルダ

SELECT * FROM user_table WHERE id = :user AND PASSWORD = password(:pass)

プレースホルダに値をセットするには、メソッドの引数に値を指定するか、プレースホルダに変数をバインドし値を代入する方法があります。

bindParam

bindParamを使用するとプレースホルダと変数を対応付けできます。

$stm = $db->prepare('INSERT INTO t VALUES (?,?)');
$stm->bindParam(1,$a);
$stm->bindParam(2,$b);
$stm->execute();

$stm = $db->prepare('INSERT INTO t VALUES (:a,:b)');
$stm->bindParam(':a',$a);
$stm->bindParam(':b',$b);
$stm->execute();

bindValue

第一引数にSQL文字列の中に埋め込まれたパラメータ部分の文字列を指定する
第二引数は実際の値
第三引数にはデータ型を示すPDOのクラス定義を指定します

PDO::PARAM_INT INT FLOAT型などの整数型
PDO::PARAM_STR デフォルト値でVARCHAR TEXTなどのstring型
PDO::PARAM_NULL NULL
PDO::PARAM_LOB BLOBなどのラージオブジェクト
PDO::PARAM_BOOL 論理値
$stm = $db->prepare('INSERT INTO t VALUES (:a,:b)');
$stm->bindValue(':a',$a,PDO::PARAM_INT);
$stm->bindValue(':b',$b,PDO::PARAM_INT);
$stm->execute();

トランザクション処理

トランザクション処理を使用すると複数のデータベース更新を単一の処理としてひとまとめにすることが可能です。
この機能は、すべてのデータベース製品がサポートしているわけではありません、データベースやデータベース内で使用しているエンジンがサポートしているかどうかを事前に確認しておく必要があります。

トランザクションは開始メソッドから終了メソッドのコミットorロールバックを実行させます。
コミットはトランザクション内のすべてのSQL文操作を確定させます。
ロールバックはトランザクション内でエラーが起きた場合、トランザクション内でそれまでに実行されたSQLの操作すべてをキャンセルできます。

try{
	$dsn = 'mysql:host=localhost;dbname=test';
	$user = '';
	$pass = '';
	$db = new PDO($dsn,$user,$pass);
	//トランザクション処理開始
	$db->beginTransaction();
	$stm = $db->prepare('DROP TABLE IF EXISTS t');
	$stm->execute();
	$stm = $db->prepare('CREATE TABLE t (a INT)');
	$stm->execute();
	$stm = $db->prepare('INSERT INTO t VALUES (:a) ');
	$stm->bindValue(':a',1);
	$stm->execute();
	//コミット
	$db->commit();
} catch (PDOException $e){
	//ロールバック
	echo $e->getMessage();
}

もし、PHP内でトランザクションを実行したにもかかわらず、コミットもロールバックもしないまま終わった場合は自動ロールバックが実行されます。

オートコミット機能

使用するライブラリによってはオートコミット機能を持つものがある。
オートコミット機能がonになっている場合、SQLの実行ごとにコミットが自動的におこなわれる。
トランザクションを使用したい場合は、offにしておく必要があります。

まとめ

しばらくPDOを触っていなかったこともあり再び勉強しました。
フレームワークを使わずにソースを書いていると、いかに自分がフレームワークの恩恵を受けてきたのか痛感します。
今後は自分でフレームワークを作りたいところですね。

SNSでシェア

Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0