PEAR MDB2以外の方法
PHPでMySQLを操作しようとしたときに、「どうしてこんなにたくさんの操作方法が用意されているのだろう」と思ったことはないでしょうか。筆者はよくそう思います(日時の扱いでもそうでした。「PHPにおける日付と時刻の混乱」を参照)。実際、筆者の作業マシンのPHPには、MySQLを操作する基本的な手段として、次のようなものが用意されています(より高度なライブラリとして、Zend_DbやPEAR DB_DataObjectがありますが、本稿では扱いません。「Zend Framework入門」等を参照してください)。
- PEAR DB(開発終了。PEAR MDB2に移行すること)
- PEAR MDB(開発終了。PEAR MDB2に移行すること)
- PEAR MDB2(PEARのデータベース接続ライブラリ)
- MySQL(MySQL 4.1.1以前用の内蔵関数群)
- MySQLi(MySQL 4.1.2以降用の内蔵関数群・クラスライブラリ)
- PHP Data Objects (PDO)(PHP 5.1以降にバンドルされているPECL拡張モジュール)
「機能拡張に柔軟に対応できるように設計する」という原則は、PHPにはあてはまらないのかもしれません。Perlでよく言われる「There's More Than One Way To Do It. (TMTOWTDI) 」ということともちょっと違うと思います。
混乱するのは確かなのですが、開発が終了したもの以外ならば、どれを選んでも実は問題ありません。実際、本稿で紹介したMDB2の機能は、MySQLiやPDOでも実現できます(mysqli.phpとpdo.phpに実装したので参考にしてください)。
結局どれを使うべきか?
これはなかなか難しい質問です。はっきりと決めることはできないと思います。以下の項目を参考に自分なりの答えを出してみてください。
- いずれも基本的な機能は備えています。
- MySQLiはたいていの環境で事前準備なしに使えます(プリペアードステートメントやトランザクションを利用できるのはPHP 5以降)。
- MySQLiはMySQLにしか対応していません。
- PEAR MDB2は事前にドライバのインストールが必要な場合があります。
- PEAR MDB2はMySQLiやPDOに比べて低速です。
- PDOのためにはPHP 5.1以降が必要です。
たとえば、開発の途中でデータベース管理システムが変更になる可能性があるときはMySQLi以外を使ってください(MySQLiは、バージョンによって機能に大きな違いがあることにも注意)。データベース接続の速度が非常に重要な場合にはPEAR MDB2以外になるでしょう。
おわりに
PEAR MDB2を用いて、PHPからMySQLを操作する基本的な方法を確認しました。
プログラムからデータベースを操作するときには、プリペアードステートメントを利用するのが基本です。たいていの場合においては、プリペアードステートメントによってデータを適切に扱えますし、SQLインジェクションという攻撃にも対処することができます。まずはこの点をしっかり確認してください。
MDB2はこのプリペアードステートメントを初めとして、プログラムからデータベースを操作する際に必要となる基本的な機能をすべて備えています。PHPにはMDB2以外にもデータベースを操作する方法がいくつもありますが、MDB2は利用するデータベースやPHPのバージョンの制約がかなり少なく、たいていの環境で利用可能なはずなので、試してみることをお勧めします。
付録:ベンチマーク
PEAR MDB2はMySQLiやPDOに比べて低速になることを、簡単なベンチマークで確認しましょう。プリペアードステートメントによるデータの挿入と、単純クエリによるデータの取得を繰り返します(benchmark.phpに記述)。
ここで行っている計算の結果が、nを$maxNum
として、
n(n+1)(n+2)/6
になることは、少し考えればすぐにわかりますが、ここでは少し冗長な方法で計算しています。データベースの操作にかかる時間を測定するためです。本当は、接続も繰り返したほうが実際の感覚に近くなるかもしれませんが、接続にかかる時間は、MySQLの設定などPHP以外の部分に大きく依存すると思われるます。そのため、各手法で接続は1回だけにしています。
PEAR MDB2の場合は次のようになります。MySQLiとPDOの場合については、benchmark.phpを参照してください。
$maxNum=1000; $start=time(); require_once 'mdb2init.php'; $db->exec("TRUNCATE TABLE books"); $sum=0; for($i=1;$i<=$maxNum;++$i){ $stmt=$db->prepare("INSERT INTO books (price) VALUES (?)"); $stmt->execute(array($i)); $rs=$db->query("SELECT price FROM books"); while($row = $rs->fetchRow()) $sum+=$row[0]; } $t=time()-$start; echo "<p>MDB2: {$t}秒, {$sum}</p>";
結果
Athlon 64 X2 3800+、メモリ2GbのWindows XPマシン、インストール直後のXAMPP 1.6.4を使って測定した結果は表のようになりました。
手法 | 時間 |
MDB2 | 13s |
MySQLi | 4s |
PDO | 4s |
MDB2は他の2つに比べてかなり遅いようです。ただし、データベース操作はアプリケーションの一部でしかありませんから、この結果の差がそのままアプリケーションのパフォーマンスの差になるわけではありません。