PHP/PDO/接続の管理
接続の確立
PDOでは、接続を行うデータベースの情報(URL,ユーザー,パスワード)をもとにPDOクラスのオブジェクトを生成することで、データベースへの接続を確立する。
この時点でエラーが発生した場合、例外PDOExceptionが発生する。同オブジェクトをキャッチすることで例外処理を行う。
接続の確立のテストコード
try {
// PDOオブジェクトの作成
$pdo = new PDO("mysql:host=localhost;dbname=blog", "root", "");
$pdo = null;
} catch (PDOException $e) {
print $e->getMessage();
$pdo = null;
die();
}
?>
結果
とくになし。
例外を発生させてみる
try {
// PDOオブジェクトの作成。存在しないデータベースを指定。
$pdo = new PDO("mysql:host=localhost;dbname=blog!!!!!", "root", "");
$pdo = null;
} catch (PDOException $e) {
var_dump($e);
$pdo = null;
die();
}
?>
結果
PDOExceptionクラスのオブジェクト$eの内容
["message:protected"]=>
string(46) "SQLSTATE[42000] [1049] Unknown database ‘blog!!!!!’"
["string:private"]=>
string(0) ""
["code:protected"]=>
int(0)
["file:protected"]=>
string(25) "C:\xampp\htdocs\pdo\2.php"
["line:protected"]=>
int(4)
["trace:private"]=>
array(1) {
[0]=>
array(6) {
["file"]=>
string(25) "C:\xampp\htdocs\pdo\2.php"
["line"]=>
int(4)
["function"]=>
string(11) "__construct"
["class"]=>
string(3) "PDO"
["type"]=>
string(2) "->"
["args"]=>
array(3) {
[0]=>
string(32) "mysql:host=localhost;dbname=blog!!!!!"
[1]=>
string(4) "root"
[2]=>
string(0) ""
}
}
}
["errorInfo"]=>
NULL
}
ただし、var_dumpだとデータベースのURL、ホスト名、パスワードがすべて表示されてしまうので、開発時以外は使っちゃダメ。
各値を取得する場合は、PDOExceptionのメソッドを利用する。
/* プロパティ */
public string $errorInfo ;
protected string $message ;
protected string $code ;
/* Inherited methods */
final public string Exception::getMessage ( void )
final public int Exception::getCode ( void )
final public string Exception::getFile ( void )
final public string Exception::getLine ( void )
final public array Exception::getTrace ( void )
final public string Exception::getTraceAsString ( void )
public string Exception::__toString ( void )
final private string Exception::__clone ( void )
}
接続の終了
接続を確立したPDOオブジェクトにNULLを代入することで、接続を終了する。
終了処理についての注意
PHP5より、try-catchによる例外処理がサポートされたが、Javaでいうfinally句がサポートされていない。
これにより、終了処理を重複させて記述しなければならない。
try {
// PDOオブジェクトの作成。存在しないデータベースを指定。
$pdo = new PDO("mysql:host=localhost;dbname=blog!!!!!", "root", "");
// ↓これ
$pdo = null;
} catch (PDOException $e) {
var_dump($e);
// ↓これ
$pdo = null;
die();
}
?>
ちなみにNULL代入を忘れた場合、接続はスクリプトの終了時に切断される。
PHP/PDO/問い合わせ(select)
selectの発行(単純なクエリー)
従来の単純なクエリ。ただし、特別理由がない限り、後述のプリペアドステートメントを利用するほうがよい。
try {
$pdo = new PDO("mysql:host=localhost;dbname=pdo", "root", "");
// 文字化け対策
$pdo->query("SET NAMES sjis");
$result = $pdo->query("select * from blog");
foreach($result as $row) {
print_r($row);
}
$pdo = null;
} catch (PDOException $e) {
var_dump($e);
$pdo = null;
die();
}
?>
結果
(
[id] => 1
[0] => 1
[title] => 今日の日記
[1] => 今日の日記
=> べんきょうしました。
[2] => べんきょうしました。
)
Array
(
[id] => 2
[0] => 2
[title] => 昨日の日記
[1] => 昨日の日記
=> はやおきしました。
[2] => はやおきしました。
)
連想配列に、列名とインデックスで結果が格納される。
selectの発行(プリペアドステートメント)
PDOオブジェクトのprepareメソッドを利用してPDOStatementクラスのオブジェクトを取得することで、プリペアドステートメントを利用することができる。
プリペアドステートメントを使う理由
抜粋
-PDO側が、パラメータを自動的にエスケープする。
-クエリを連続して実行するときに、クエリの解析(パース)が一度しか行われないため、連続クエリが高速に実行できる。
コード
try {
$pdo = new PDO("mysql:host=localhost;dbname=pdo", "root", "");
// 文字化け対策
$pdo->query("SET NAMES sjis");
$stmt = $pdo->prepare("select * from blog where title like :WORD");
$stmt->bindValue(":WORD", "%今日%");
$result = $stmt->execute();
if($result){
while ($row = $stmt->fetch()) {
print_r($row);
}
}
$pdo = null;
} catch (PDOException $e) {
var_dump($e);
$pdo = null;
die();
}
?>
結果
(
[id] => 1
[0] => 1
[title] => 今日の日記
[1] => 今日の日記
=> べんきょうしました。
[2] => べんきょうしました。
)
バインドメソッド
3種類のバインドメソッドが用意されている
-bindColumn
–カラムを PHP 変数にバインドする
–データベースのカラムにPHP変数をバインドする。値は実行時評価(参照)。
-bindParam
–指定された変数名にパラメータをバインドする 値は実行時評価(参照)。
-bindValue
–値そのものをバインドする

