3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。(jehupc.exblog.jpから移転中)

(PHP)PDOで、SQLiteにアクセスしてみた

PHPで多分初めてSQLiteを使おうと思ってます。

SQLiteドライバから直接クエリを投げてもいいんですが、PDO(PHP Data Object)というDBアクセスの抽象化レイヤがあるみたいで、これを使うとどのデータベースを使っているかを気にすることなく使え、DBを移行した際にもさしてソースに変更加えなくていいようです。

(ただし、O/Rマッピングをしてくれるわけではないので、完全な抽象化をしたければCakePHPのようなフレームワークを使った方がいいかもしれません。)

DBファイルやテーブルの作成自体は、SQLiteManager を使いました。

なお、PDOを使うにはDBごとにPDOのモジュールがインストールし、php.iniで使うように設定しなければなりません。(まぁ大抵のレンタルサーバはsqlite2のPDOモジュールは入ってると思いますが。。。)

まず接続は PDO クラスのインスタンスを作成するだけでいいようです。

作成した PDO インスタンスの変数に null を入れたり、unset(変数)を実行するだけで切断となります。

PDO->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); としておくと、エラー発生時は PDOException が発生するので、try catch で囲むようにしておけばOKです。

SQLをすぐに実行する場合は、下記のようにPDOインスタンスのqueryメソッドを実行し、引数にクエリ文を入れたらいいようです。結果は PDOStatement オブジェクトとして返ってきます。 PDOStatement オブジェクトの fetchAll メソッドを使うと、結果を全て配列にしてくれるので、PHPでは操作しやすいですね。

try {

// DBに接続する

$db = new PDO( 'sqlite2:./test.sqlite', '', '' );

$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

 

/* ..... DBアクセス ..... */

//データを取得し、それを表示

foreach( $db->query( 'SELECT * FROM testtbl ORDER BY id' ) as $row ) {

print 'id = ' . $row[ 'id' ] . ', value = ' . $row[ 'value' ] . "\n";

}

 

//データを取得し、全て配列化する

$dbRes_subject_cate = $db->query( 'SELECT * FROM testtbl ORDER BY id' )->fetchAll();

 

echo "

";

print_r( $dbRes_subject_cate );

echo "

";

 

// DBから切断する ( $db = null; も可能)

unset( $db );

 

} catch( PDOException $ex ) {

// DBアクセス時にエラーとなった時

print 'DBエラー : ' . $ex->getMessage();

unset( $db );

die();

}

パラメータ(プレースホルダ)を使ってSQLクエリを投げることもできます。(プリペアドステートメント)

パラメータは名前付きパラメータと名前無パラメータが使えるようです。

パラメータは配列で指定することもできますし、PDOStatement オブジェクトの bindParam メソッドでも指定できます。

下記のような感じです。

try {

// DBに接続する

$db = new PDO( 'sqlite2:./test.sqlite', '', '' );

$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

 

//******名前付きプレースホルダ(値配列指定)

$stmt = $db->prepare( 'INSERT INTO test( id , value ) VALUES ( :id , :value )' );

//配列で指定するときは実行メソッド(execute)の引数にパラメータの値配列を指定

$res = $stmt->execute(array(':id' => 1 , ':value' => 'test') );

echo "結果行数:" .$res . "
"
;

 

//******名前付きプレースホルダ(bindParamメソッドにて値指定)

$stmt = $db->prepare( 'INSERT INTO test( id , value ) VALUES ( :id , :value )' );

$value = "test";

//bindParamメソッドでは値のリテラルを引数に指定してはいけないので注意。

$stmt->bindParam( ':value', $value );

$id=1;

$stmt->bindParam( ':id', $id );

//bindParamメソッドの後からexecuteを実行する前なら値の変更可能

$id=2;

//クエリ実行

$res = $stmt->execute();

echo "結果行数:" .$res . "
"
;

 

//******名前無プレースホルダ(値配列指定)

$stmt = $db->prepare( 'INSERT INTO test( id , value ) VALUES ( ? , ? )' );

//配列で指定するときは実行メソッド(execute)の引数にパラメータの値配列を指定

$res = $stmt->execute(array( 5 , 'test5') );

echo "結果行数:" .$res . "
"
;

 

//******名前無プレースホルダ(bindParamメソッドにて値指定)

$stmt = $db->prepare( 'INSERT INTO test( id , value ) VALUES ( ? , ? )' );

$id=6;

$value = "test";

$stmt->bindParam( 1, $id ); //1番目のパラメータ指定

$stmt->bindParam( 2, $value ); //2番目のパラメータ指定

//クエリ実行

$res = $stmt->execute();

echo "結果行数:" .$res . "
"
;

$db=null;

}catch( PDOException $ex ) {

// DBアクセスができなかったとき

print 'DBにデータ追加失敗。 : ' . $ex->getMessage();

unset( $db );

die();

}

また、トランザクションを有効にするには、下記のようにしてやるといいようです。

// DBに接続する

$db = new PDO( 'sqlite2:./test.sqlite', '', '' );

//トランザクション開始

$stmt=$db->beginTransaction();

//クエリを実行

$db->query('INSERT INTO test( id , value ) VALUES ( 10 , testetst )' );

//コミット

$stmt=$db->commit();

参考:

PDOでサクサクDB開発(1/9):CodeZine

今からスタート! PHP:第11回 データベースへのアクセス [PDO編]|gihyo.jp

PHP: PDO - Manual:リファレンス

PDO クエリの発行