PHPPDO 学習ノート lib.culog.cn 2007 年 11 月 13 日 09:36 著者: Liu Shui Meng Chun [大、中、小]
■PDOとは?
POD (PHP Data Object) 拡張機能は PHP5 で追加されました。PHP6 では、データベースへの接続にデフォルトで PDO が使用されます。PHP6 では、PDO 以外の拡張機能がすべて削除されます。この拡張機能は、データベースにアクセスするための PHP 組み込みクラス PDO を提供し、異なるデータベースが同じメソッド名を使用してデータベース接続の不一致の問題を解決します。
Windows での開発用に構成しました。
■PDO の目標は、さまざまな RDBMS ライブラリの共通機能を統合しながら、より高度な機能を排除しない、軽量で明確で便利な API を提供することです。 PHP スクリプトを介して、オプションで高度な抽象化/互換性を提供します。
■PDOの特徴:
パフォーマンス。 PDO は、既存のデータベースのスケーリングの成功と失敗について最初から学びました。 PDO のコードはまったく新しいため、PHP 5 の最新機能を活用するためにパフォーマンスをゼロから再設計する機会があります。 能力。 PDO は、RDBMS の固有の機能に簡単にアクセスできるようにしながら、基盤として一般的なデータベース機能を提供するように設計されています。 単純。 PDO は、データベースの操作を簡単にするように設計されています。 API はコードに強制的に組み込まれることはなく、各関数呼び出しが何を行うのかを明確にします。 実行時に拡張可能。 PDO 拡張機能はモジュール式であるため、PHP プログラム全体を再コンパイルまたは再インストールすることなく、実行時にデータベース バックエンドのドライバーを読み込むことができます。たとえば、PDO_OCI 拡張機能は、PDO 拡張機能の代わりに Oracle データベース API を実装します。 MySQL、PostgreSQL、ODBC、Firebird 用のドライバーもあり、さらに多くのドライバーが開発中です。
■PDOのインストール
ここにあるのは、WINDOWS での開発用の PDO 拡張機能です。Linux でインストールして構成したい場合は、他の場所を探してください。
バージョン要件:
php5.1 以降のバージョンのプログラム パッケージに既に含まれています。
php5.0.x の場合は、pecl.php.net からダウンロードして、拡張ライブラリ (PHP が存在するフォルダーの ext フォルダー) に置く必要があります。
マニュアルには、5.0 より前のバージョンでは PDO 拡張機能を実行できないと記載されています。
構成:
pdo をサポートするように php.ini 設定ファイルを変更します (php.ini を理解していない場合は、phpinfo() 関数を呼び出すときに表示される php.ini を変更する必要があることをまず確認してください)。
バンドル
extension=php_pdo.dll の前のセミコロンを削除します。セミコロンは php 設定ファイルのコメント記号です。この拡張子は必須です。
他にもあります
;extension=php_pdo.dll
;extension=php_pdo_firebird.dll
;extension=php_pdo_informix.dll
;extension=php_pdo_mssql.dll
;extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll
;extension=php_pdo_oci8.dll
;extension=php_pdo_odbc.dll
;extension=php_pdo_pgsql.dll
;extension=php_pdo_sqlite.dll
各拡張子に対応するデータベースは次のとおりです。
ドライバー名サポートされるデータベースPDO_DBLIBFreeTDS / Microsoft SQL Server / SybasePDO_FIREBIRDFirebird/Interbase 6PDO_INFORMIXIBM Informix Dynamic ServerPDO_MYSQLMySQL 3.x/4.xPDO_OCIOracle Call InterfacePDO_ODBCODBC v3 (IBM DB2、unixODBC、win32 ODBC)PDO_PGSQLPostgreSQLPDO_SQLITESQLite 3 および SQLite 2
どのデータベースを使用するか、対応するデータベースを入力するだけです展開する前にコメント記号「;」を削除してください。
■PDOを利用する
ここでは、mysql がインストールされていることを前提としています。そうでない場合は、まず mysql5.0.22 をインストールする方法を見つけてください。MySQL 4.0.26 を使用している人もそれを使用できます。
★データベース接続:
次の例を使用して PDO 接続データベースを分析します。
<?php
$dbms='mysql'; //データベース タイプ Oracle は ODI を使用します。開発者にとって、別のデータベースを使用する場合は、これを変更するだけでよく、それほど多くの関数を覚える必要はありません。
$host='localhost';//データベースホスト名
$dbName='test' //使用するデータベース
$user='root' //データベース接続ユーザー名
$pass=''; // 対応するパスワード
$dsn="$dbms:host=$host;dbname=$dbName";
//
試す{
$dbh=newPDO($dsn,$user,$pass);//PDO オブジェクトの初期化とは、データベース接続オブジェクト $dbh の作成を意味します
echo "接続が成功しました<br/>";
/*検索操作を実行することもできます
foreach($dbh->query('SELECT * from FOO')as$row){
print_r($row);//echo($GLOBAL) を使用してこれらの値を確認できます。
}
*/
$dbh=null;
}catch(PDOException$e){
die("エラー!: ".$e->getMessage()."<br/>");
}
//デフォルトでは、これは長い接続ではありません。データベースへの長い接続が必要な場合は、最後にパラメータを追加する必要があります。array(PDO::ATTR_PERSISTENT => true) となります。
$db=newPDO($dsn,$user,$pass,array(PDO::ATTR_PERSISTENT=>true))
;
★データベースクエリ:
上記のクエリはすでに実行していますが、次のクエリも使用できます。
<?php
$db->setAttribute(PDO::ATTR_CASE,PDO::CASE_UPPER); //属性を設定します
$rs=$db->query("SELECT * FROM foo");
$rs->setFetchMode(PDO::FETCH_ASSOC);
$result_arr=$rs->fetchAll();
print_r($result_arr);
?>
上記では setAttribute() メソッドが使用されているため、フィールド名を強制的に大文字にするために 2 つのパラメーターが入力されています。 PDO::setAttribute() のパラメータは次のとおりです。
PDO::ATTR_CASE: 以下に詳述する形式で列名を強制します (2 番目のパラメータ)。
PDO::CASE_LOWER:PDO
を強制的に小文字にします。
: :CASE_NATURAL: 列名は元の方法に従います
。 PDO::CASE_UPPER: 列名を強制的に大文字にします。
PDO::ATTR_ERRMODE: エラー メッセージ。
PDO::ERRMODE_SILENT: エラー情報を表示せず、エラー コードのみを
表示します。
PDO::ERRMODE_EXCEPTION: 例外をスローします。
PDO::ATTR_ORACLE_NULLS (ORACLE だけでなく、他のデータベースにも有効): ) データベースから返される NULL 値に対応する値を php で指定します。
PDO::NULL_NATURAL: 変更されません。
PDO::NULL_EMPTY_STRING: 空の文字列が NULL に変換されます。
PDO::NULL_TO_STRING: NULL が空の文字列に変換されます。
PDO::ATTR_STRINGIFY_FETCHES: フェッチ時に数値を文字列に変換します。 bool が必要です。
PDOStatement から派生したユーザー指定のステートメント クラスを設定します。 Requiresarray(string classname, array(mixedconstructor_args) )) .
PDO::ATTR_AUTOCOMMIT (OCI、Firebird、MySQL で使用可能): すべてのステートメントを自動コミットするかどうか。
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY (MySQL で使用可能): バッファーされたクエリを使用します。
この例の $rs->setFetchMode(PDO::FETCH_ASSOC); は PDOStatement::setFetchMode() であり、戻り値の型の宣言です。
以下のようなものがあります。
PDO::FETCH_ASSOC -- 連想配列形式
PDO::FETCH_NUM -- 数値インデックス配列形式
PDO::FETCH_BOTH -- どちらも配列形式で使用できます。これがデフォルトです。
PDO::FETCH_OBJ -- 前の mysql_fetch_object() と同様のオブジェクト形式。
戻り値の型宣言 (PDOStatement::メソッド名) については、マニュアルを参照してください。
★データの挿入、更新、削除、
$db->exec("mid=43 の `xxxx_menu` から削除");
上記の操作を簡単に要約すると、次のようになります。
クエリ操作は主に PDO::query()、PDO::exec()、PDO::prepare() です。
PDO::query() は主に、記録された結果を返す操作、特に SELECT 操作に使用されます。
PDO::exec() は主に、INSERT、UPDATE、DELETE などの結果セットを返さない操作に使用されます。返される結果は、現在の操作によって影響を受ける列の数です。
PDO::prepare() は主に前処理操作です。前処理で SQL ステートメントを実行するには $rs->execute() を使用する必要があります。このメソッドはパラメータをバインドすることができ、この記事では簡単に説明できません。 . 全員 マニュアルやその他のドキュメントを参照できます。
結果セットを取得するための主な操作は、PDOStatement::fetchColumn()、PDOStatement::fetch()、PDOStatement::fetchALL() です。
PDOStatement::fetchColumn() は、フェッチ結果で指定された最初のレコードのフィールドです。デフォルトは最初のフィールドです。
PDOStatement::fetch() を使用してレコードを取得します。
PDOStatement::fetchAll() は、すべてのレコード セットを 1 つにまとめて結果を取得するために、PDOStatement::setFetchMode を通じて必要な結果セットのタイプを設定できます。
周囲の操作も 2 つあり、1 つは PDO::lastInsertId() と PDOStatement::rowCount() です。 PDO::lastInsertId() は最後の挿入操作を返し、主キー列の型は最後の自動インクリメント ID です。
PDOStatement::rowCount() は主に、PDO::query() および PDO::prepare() の DELETE、INSERT、および UPDATE 操作の影響を受ける結果セットに使用され、PDO::exec() メソッドには無効ですおよび SELECT 操作。
★トランザクションと自動送信
この時点で、PDO を介して mysql に接続しました。クエリを発行する前に、PDO がトランザクションをどのように管理するかを理解する必要があります。これまでトランザクションに接したことがない場合は、まずトランザクションの 4 つの特性、つまり原子性、一貫性、分離性、耐久性、つまり ACID を理解する必要があります。平たく言えば、トランザクション内で実行されるすべての作業は、それが段階的に実行される場合でも、作業がデータベースに安全に適用され、作業の送信中に他の接続からのリクエストの影響を受けないことが保証されます。 。 影響。トランザクション作業はリクエストに応じて (まだコミットしていない場合) 自動的に取り消すことができるため、スクリプトでのエラー処理がはるかに簡単になります。
トランザクションは通常、変更のバッチを蓄積し、それらを同時に有効にすることによって実装されます。この利点は、これらの更新の効率を大幅に向上できることです。言い換えれば、トランザクションによってスクリプトが高速化され、潜在的により堅牢になる可能性があります (ただし、そのような利点を得るにはトランザクションを正しく使用する必要があります)。
残念ながら、すべてのデータベースがトランザクションをサポートしているわけではありません (Mysql5 はトランザクションをサポートしていますが、mysql4 は知りません)。そのため、最初に接続が開かれたとき、PDO はいわゆる「自動コミット」モードで実行する必要があります。オートコミット モードは、データベースがトランザクションをサポートしている場合は、実行するすべてのクエリに独自の暗黙的なトランザクションがあり、データベースがトランザクションをサポートしていない場合は、すべてのクエリにそのようなトランザクションが存在しないことを意味します。トランザクションが必要な場合は、PDO::beginTransaction() メソッドを使用してトランザクションを開始する必要があります。基礎となるドライバーがトランザクションをサポートしていない場合、PDOException がスローされます (エラー処理設定に関係なく、これは常に致命的なエラー状態です)。トランザクション内で実行中のコードが成功したかどうかに応じて、トランザクション内で PDO::commit() または PDO::rollBack() を使用してトランザクションを終了できます。
スクリプトが終了するとき、または接続が閉じられようとするときに、未処理のトランザクションがある場合、PDO はトランザクションを自動的にロールバックします。これは、スクリプトが異常終了した場合に不整合を回避するための安全対策です。トランザクションが明示的にコミットされていない場合は、どこかで不整合が発生すると想定されるため、データのセキュリティを維持するためにロールバックが実行されます。
//http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0505furlong/index.htmlの例
試す{
$dbh=新しい PDO('odbc:SAMPLE','db2inst1','ibmdb2',
配列(PDO_ATTR_PERSISTENT=>true));
echo「接続されましたn」;
$dbh->setAttribute(PDO_ATTR_ERRMODE,PDO_ERRMODE_EXCEPTION);
$dbh->beginTransaction();
$dbh->exec("スタッフ (ID、最初、最後) の値に挿入 (23, 'Joe', 'Bloggs')");
$dbh->exec("給与変更に挿入 (ID、金額、変更日)
値(23, 50000, NOW())");
$dbh->commit();
}catch(例外 $e){
$dbh->rollBack();
echo"失敗: ".$e->getMessage();
}
上の例では、ID 番号 23 を持つ新入社員用のエントリのセットを作成するとします。個人の基本データを入力することに加えて、従業員の給与も記録する必要があります。両方の更新を個別に実行するのは簡単ですが、両方の更新を beginTransaction() 呼び出しと commit() 呼び出しに含めることで、完了するまで他の人が変更を確認できないようにすることができます。エラーが発生した場合、catch ブロックはトランザクションの開始以降に発生したすべての変更をロールバックし、エラー メッセージを出力します。
更新はトランザクション内で行う必要はありません。複雑なクエリを発行してデータを抽出し、その情報を使用してさらなる更新とクエリを構築することもできます。トランザクションがアクティブな場合、作業の進行中に他のユーザーが変更を加えることができないことが保証されます。実際、これは 100% 正しいわけではありませんが、これまでトランザクションについて聞いたことがない場合には良い入門書となります。
★プリペアド ステートメントとストアド プロシージャ より成熟したデータベースの多くは、プリペアド ステートメントの概念をサポートしています。準備されたステートメントとは何ですか?プリペアド ステートメントは、実行する SQL のコンパイルされたテンプレートと考えることができ、変数パラメーターを使用してカスタマイズできます。プリペアド ステートメントには 2 つの大きな利点があります。
クエリは 1 回解析 (または準備) するだけで済みますが、同じパラメータまたは異なるパラメータを使用して複数回実行できます。クエリの準備が完了すると、データベースはクエリを実行するための計画を分析、コンパイル、最適化します。複雑なクエリの場合、このプロセスには時間がかかり、異なるパラメータを使用して同じクエリを複数回繰り返す必要がある場合、アプリケーションの速度が大幅に低下する可能性があります。準備されたステートメントを使用すると、分析/コンパイル/最適化サイクルの繰り返しを回避できます。簡単に言えば、準備されたステートメントは使用するリソースが少ないため、より高速に実行されます。
準備されたステートメントに指定されるパラメータは引用符で囲む必要はありません。これらはドライバーによって処理されます。アプリケーションが準備されたステートメントを排他的に使用する場合、SQL 侵入は発生しないことが保証されます。 (ただし、クエリの他の部分が信頼できない入力に基づいている場合は、依然としてリスクが存在します)。
プリペアド ステートメントは非常に便利であるため、PDO は目標 4 で設定されたルールを実際に破ります。ドライバーがプリペアド ステートメントをサポートしていない場合、PDO はプリペアド ステートメントをエミュレートします。
例: PDO アプリケーションの例:
<?php
'
;//データベース タイプ Oracle は ODI を使用します。開発者は、これを変更する限り、それほど多くの関数を覚える必要はありません。
ホスト名
$dbName='test';//使用するデータベース
$user='root';//データベース接続ユーザー名
$pass='';//対応するパスワード
$dsn="$dbms:host=$host;dbname= $dbName";
classdbextendsPDO{
publicfunction__construct(){
試す{
parent::__construct("$GLOBALS[dsn]",$GLOBALS['user'],$GLOBALS['pass']);
}catch(PDOException$e){
die("エラー: ".$e->__toString()."<br/>");
}
}
publicfinalfunctionquery($sql){
試す{
returnparent::query($this->setString($sql));
}catch(PDOException$e){
die("エラー: ".$e->__toString()."<br/>");
}
}
privatefinalfunctionsetString($sql){
echo "$sql を処理したい";
$sql を返す;
}
$
db=newdb();
$db->setAttribute(PDO::ATTR_CASE,PDO::CASE_UPPER);
foreach($db->query('SELECT * from xxxx_menu')as$row){
print_r($row);
}
$db->exec('xxxx_menu` から削除 (mid=43)');
?>