私たちのところでは、プリペアド・ステートメントやトランザクション・サポートなどのために、mysqliとPDOを使い分けることにしています。あるプロジェクトではどちらかを使い、あるプロジェクトではもう一方を使っています。他のRDBMSに移行する現実的な可能性はほとんどありません。
私がPDOを好む理由は、PDOではプリペアドステートメントに名前付きパラメータが使えるということだけです。
プロジェクトを統合し、1つのアプローチを使用するようにするために、標準としてどちらかを選択する他の長所と短所はありますか?
さて、オブジェクト指向の側面、準備されたステートメント、それが標準になるという事実などについて議論できます。 しかし、ほとんどの場合、誰かを説得することはキラー機能でよりうまく機能することを知っています。 だからそれはあります:
PDOの本当に良い点は、データをフェッチして、オブジェクトに自動的に挿入できることです。 ORMを使用したくない(これは単なるクイックスクリプトであるため)が、オブジェクトマッピングが好きな場合は、本当にクールです。
class Student {
public $id;
public $first_name;
public $last_name
public function getFullName() {
return $this->first_name.' '.$this->last_name
}
}
try
{
$dbh = new PDO("mysql:host=$hostname;dbname=school", $username, $password)
$stmt = $dbh->query("SELECT * FROM students");
/* MAGIC HAPPENS HERE */
$stmt->setFetchMode(PDO::FETCH_INTO, new Student);
foreach($stmt as $student)
{
echo $student->getFullName().'<br />';
}
$dbh = null;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
PDOを使い始めたのは、ステートメントのサポートがより優れているからだと思います。私はActiveRecordのようなデータアクセスレイヤーを使っていますが、動的に生成されるステートメントを実装するのがはるかに簡単です。MySQLi' のパラメータバインディングは1つの関数/メソッド呼び出しで行わなければならないので、実行時までバインディングしたいパラメータの数がわからない場合は、selects に call_user_func_array()
(これが正しい関数名だと思います) を使用せざるを得ません。そして、単純な動的結果バインディングのことは忘れてください。
何より、私がPDOを気に入っているのは、それが非常に合理的な抽象レベルだからです。SQLを書きたくないような完全に抽象化されたシステムで使うのも簡単ですが、より最適化された純粋なクエリータイプのシステムを使うのも簡単ですし、その2つを混在させるのも簡単です。
覚えておくべきことが他にもあります。今のところ(PHP 5.2)PDOライブラリは< b> buggy< / b>です。 奇妙なバグでいっぱいです。 例:変数に「PDOStatement」を保存する前に、大量のバグを回避するために、変数は「unset()」である必要があります。 これらのほとんどはPHP 5.3で修正されており、2009年の初めにPHP 5.3でリリースされる予定です。これにはおそらく他の多くのバグがあります。 安定したリリースが必要な場合はPHP 6.1にPDOを使用し、コミュニティを支援する場合はPHP 5.3にPDOを使用することに焦点を当てる必要があります。
PDOに関するもう1つの注目すべき(良い)違いは、PDO :: quote()
メソッドが自動的に囲む引用を追加するのに対し、mysqli :: real_escape_string()
(およびsimilars)はしない:
PDO :: quote()は、入力文字列(必要な場合)の周りに引用符を配置します。 引用を使用して、入力文字列内の特殊文字をエスケープします。 基礎となるドライバーに適したスタイル。
PDOを使用すると、マスター接続とスレーブ接続を毎日セットアップしてデータベース全体に負荷を分散できるため、サイト/ウェブアプリが実際に機能するようになり、さらにPHPは標準でPDOに移行する予定です。
編集された答え。。
これらの両方のAPIでいくつかの経験をした後、ネイティブで準備されたステートメントでmysqliを使用できなくなる2つのブロッキングレベル機能があると思います。 それらはすでに2つの優れた(まだ過小評価されている)回答で言及されていました。
1。 任意の数のプレースホルダーへのバインディング値。 2。 単なる配列としてデータを返す。
(どちらもこの回答でも言及されています)。
どういうわけか、mysqliは両方で失敗しました。 最近では2番目の機能(get_result)で多少改善されていますが、mysqlndインストールでのみ機能するため、スクリプトでこの機能に依存できません。
しかし、今日までバインドバイバリューはありません。
したがって、選択肢は1つだけです: PDO 。
など、他のすべての理由。
-プレースホルダーという名前(この構文の砂糖はかなり過大評価されています)。 -さまざまなデータベースがサポートしています(実際に使用した人はいません)。 -オブジェクトにフェッチします(役に立たない構文の砂糖)。 -速度の違い(ありません)。
重要ではありません。
同時に、これらのAPIには、実際の重要な機能などがありません。
-識別子プレースホルダー。 -動的バインディングを ⁇ わしくしない複雑なデータタイプのプレースホルダー。 -短いアプリケーションコード。
したがって、実際のライフニーズをカバーするには、これらのAPIの1つに基づいて独自の抽象化ライブラリを作成し、手動で解析されたプレースホルダーを実装する必要があります。 この場合、抽象化のレベルが低いので、mysqliを好みます。
個人的にはPDOを使用していますが、これは主に好みの問題だと思います。
PDOにはSQLインジェクションに対抗するための機能(prepared statements)がありますが、SQLに気をつければmysqliでも十分実現できます。
他のデータベースに移動することは、PDOを使う理由にはあまりならない。特殊な SQL 機能を使わない限り、ある DB から別の DB に移行することは可能です。しかし、例えば "SELECT ... LIMIT 1" を使った途端に、"SELECT TOP 1 ..." となる MS-SQL に行くことはできません。というわけで、とにかくこれは問題です。
ベンチマークスクリプトでは、各メソッドが10000回テストされ、各メソッドの合計時間の差が印刷されます。 これはあなた自身の構成で行う必要があります、結果は異なると確信しています。!
これらは私の結果です。
-「 SELECT NULL」-> PGO()
は0.35秒速くなります。
-「 SHOW TABLE STATUS」-> mysqli()
約2.3秒速くなります。
-「 SELECT * FROM users」-> mysqli()
約33秒速くなります。
注:mysqliに-> fetch_row()を使用すると、列名が配列に追加されず、PGOでこれを行う方法が見つかりませんでした。ただし、-> fetch_array()を使用しても、mysqliはPGOよりわずかに遅くなりますが、PGOよりも高速です(SELECT NULLを除く)。
PDOがMySQLiが私が本当に気に入っていないことの1つは、指定されたクラスタイプのオブジェクトとして結果を返すPDOの能力です(例:. $ pdo-> fetchObject( 'MyClass')
)。 MySQLiの fetch_object()
は stdClass
オブジェクトのみを返します。