SQLiteを使うとpdoでrowCount()できない

2011/10/11 | PDO, SQLite

SQLでinsert、update、delete文を発行して、結果として影響を受けた行数を知りたい場合がある。pdoの場合、rowCount()というメソッドで知ることが出来るのだが、SQLiteでは使えないことがわかった。PHPのマニュアル中のコメントを読むと、どうやら3系からNGのようだ。

SQLはプリペアードステートメントを使って実行しているんだが、やっぱり無理なんだろうか。SQLiteはちょっといろいろ癖があるっぽい感じだ。

モジュールをインストールできないと思ったら

2009/06/30 | CLI, PDO

VPSを何台か借りているが、VPSというのは、その内情(インストール方法)を知っておかないと、恐ろしく手間取る可能性があることを改めて知った。

格安でVPSを借りているのだが、そこにはpdo_mysqlがインストールされていなかった。そこでpdo_mysqlをインストールしようとして四苦八苦したので、メモを残しておく(現状報告として、現時点ではインストールできていない)。

まず最初にしたことはRPMパッケージ探し。OSはCentOSであることがわかっているが念のため、バージョンを確認。

more /etc/redhat-release

これでバージョンが確認できた(ちなみにOSはCentOS4.7だった)。次に当該バージョンでRPMが提供されているかどうかウェブで調べる。結構調べたつもりだけど、結果として見つけられなかった。「さて、どうしようか」と考えて、次にPECLでのインストールを試みる。これには事前にいろいろなパッケージを入れておく必要がある。yumコマンドでインストールした。

yum –enablerepo=centosplus -y install php-devel php-pear mysql-devel httpd-devel

yumのリポジトリでcentosplusというのを有効にしておく必要があるみたい。ちなみにyオプションは、何を聞かれても「y」と答えなさい、という意味。ここまででPECLコマンドが利用できるようになった(PECLは確かPEARに含まれていたと思った)。そこでコマンドラインで、コマンド一発。

pecl install pdo_mysql

とりあえず応答メッセージの下のほうにcompleteと書いてあるので、いちおうOKっぽい。で、最終作業。php.iniに必要な情報(extension_dirやextension)を記述してapacheを再起動。しかしphpinfoにはpdo_mysqlは現れない。それどころかエラー。

PHP Warning: PHP Startup: pdo_mysql: Unable to initialize module
Module compiled with module API=20050922, debug=0, thread-safety=0
PHP compiled with module API=20060613, debug=0, thread-safety=0
These options need to match
in Unknown on line 0

ん~。どうやらバージョンが違うようだ。どうしてこんな食い違いが起こるんだろう。

その後、いろいろやってみたけどやっぱり動かない。なぜこんなことがおきるんだ。と思ってウェブを調べていたら、英語サイトにヒントが見つかった。そのサイトには、以下のコマンドを試してみろと書いてあった。

php -v
/usr/bin/php -v
/usr/local/bin/php -v

ん~、どういうことだろうと思いつつ、コマンドを打ってみたら、あれまぁ、結果が違うじゃん。バージョンとか。もしやと思って、rpmコマンドでインストールされているPHPのバージョンを調べてみた。そしてphpinfoでもバージョンを確認。そして愕然。

バージョンが違う。少し考えてわかった。PHPはrpmでインストールじゃなくて、コンパイルしてインストールされているんだ。しかもいろいろ調べてみたら、どうもapacheも手作業でインストールされているっぽい(だって設定ファイルの位置がRedHat系の場所と違うんだもん)。てことは、簡単お手軽RPM(もしくはyum)でインストールしようが、何しようが反映されないし、ディスクの肥やしになるだけってことか(性格にはCLI版PHPには反映されるわけだが)。

VPSにしても専用サーバにしても、開発の重要な要素である、PHPやapache、データベース周りはどのようにインストールされているのか知っておく必要がありそうだ。そもそも今回自分が借りているサーバだからいろいろできたけど、そうじゃなかったらサーバ屋さんに有償対応をお願いしたところだけど・・・、自分でやってみて初めて状況がわかったよ。

ということで、問題のpdo_mysqlはいまだにインストールできていない。今度また時間があったら再度チャレンジする予定。自分の家にあるPCにインストールしてあるんだったらとりあえずやっちゃうんだけど、レンタルしているサーバだから再インストールになったらまた費用がかかるから無理はしないことにした。

bindParamとbindValue

2008/10/01 | PDO

pdoを使ってプリペアードステートメントから各値をバインドするための関数が2つ用意されている。bindParamとbindValueだ。bindValueはコマンドが発行される都度SQL文に値がセットされるのに対し、bindParamは参照で値が渡され、execute実行時に初めて値に変換される。とりあえずマニュアルを読んで理解していたつもりだったのだが、やっぱり「つもり」だった。

$sql=’INSERT INTO table VALUES (?,?)';

上記のSQL文をプリペアードステートメントとしてセットし値をバインドしていくわけだが、こんなことをしてしていた。

$values=array(1=>3,2=>5);
foreach($values as $name => $value){
$preparedStatementObj->bindParam($name,$value);
}
$preparedStatementObj->execute();

こうすると、tableには(3,5)というデータが格納されてほしいのに、(5,5)というデータが入ってしまう。最初はまったく意味がわからなくて30分くらい悩んでしまった。そこでマニュアル読み直し。「参照渡し」「execute実行時に初めて・・・」。あ、そうか。値を渡すときに使う変数がいつも$valueだから、execute実行時には最後の$valueの値に置き換えられてしまっていたのか。

問題を解決する方法はbindValueを使うか、値をセットする都度異なる変数名を使用するか、のいずれか。どちらで試しても大丈夫だった。まさしく生兵法は怪我の基だった。

データベース操作はPDOで

2008/09/20 | PDO

最近の流行はPDOらしい。ということで今後はPDOを使うことにした。というのもZend_FrameworkでもPDO推奨らしいから。

PDOのマニュアルを見ると、プリペアードステートメントを使うことが基本のように見える。もちろんそのほうが、SQLインジェクションに悩まされることもないのだから当たり前といえば当たり前。これを機会に自分もそういう方向性で作業を進めることにする。でももうこれでPHP4には戻れない(戻るつもりもないけれど)。

とりあえず自分用に最低限のサンプルをメモしておく。

  1. $pdo=new PDO(“mysql:host=localhost; dbname=myDB”,”user”,”password”);
  2. $sql=’SELECT * FROM samples';
  3. $stmt=$pdo->prepare($sql);
  4. $stmt->execute();
  5. while($row=$stmt->fetch(PDO::FETCH_ASSOC)){
  6. var_dump($row);
  7. }

1行目でデータベースに接続してPDOオブジェクトの作成。DSNがちょっと今までと違うので注意が必要。2行目でSQLを用意して、3行目でprepareしているのだが、こんな簡単なSQLならprepareせずに直接queryメソッドを使うのもありだろう。prepareすると、その返り値はオブジェクトになっていて、以降そのオブジェクト(PDOStatementオブジェクト)に対して処理することになる。4行目でprepareしたSQL文を実行する。本来ならSQL文に「?」などのパラメータを使って値を格納する「箱」を用意しておき、3行目と4行目の間でbindParamなどを使って、それぞれの箱に値を代入して、それからSQLを実行することになる。実行結果はfetchメソッドを使って1行ずつ処理、ということだ。

特に難しいことはない。ただ今まで使っていたものに対して、汎用性を持たせて作りこむのが面倒だ。


守谷市(まちの情報ポータル) 無料アンケートレンタルjpForm.net