【PHP8.x】PDO::PARAM_INPUT_OUTPUT定数の使い方
PARAM_INPUT_OUTPUT定数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
PARAM_INPUT_OUTPUT定数は、PHPのPDO(PHP Data Objects)拡張機能において、データベースのストアドプロシージャで利用される入出力(INOUT)パラメータを表す定数です。
PDOは、様々な種類のデータベースに対して統一的なインターフェースを提供し、安全かつ効率的なデータベース操作を可能にするための拡張機能です。このPARAM_INPUT_OUTPUT定数は、特にストアドプロシージャを実行する際に、PHPからデータベースへ値を渡し、さらにストアドプロシージャ内部での処理結果として変更された値を、同じパラメータを通じてPHP側で受け取りたい場合に利用されます。
具体的には、プリペアドステートメントを使ってストアドプロシージャのパラメータをバインドする際、PDOStatement::bindParam()メソッドやPDOStatement::bindValue()メソッドの第3引数であるデータ型(data_type)としてこの定数を指定します。このとき、単独で指定するのではなく、実際にバインドする値のデータ型を示す他の定数(例えば、文字列型を表すPDO::PARAM_STRや整数型を表すPDO::PARAM_INTなど)と、ビットOR演算子(|)を使って組み合わせて指定する必要があります。例えば、PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUTのように記述します。
この定数を指定することで、PHPスクリプトはストアドプロシージャに対して初期値を提供し、ストアドプロシージャがその値を変更した場合、PHPスクリプトはその変更後の値を同じバインドされたパラメータから取得できるようになります。これにより、PHPとデータベース間でより柔軟かつ動的なデータのやり取りが可能となり、データベースに実装された複雑なビジネスロジックを効率的に活用するための重要な役割を果たします。
構文(syntax)
1<?php 2$variable = '初期値'; 3$statement->bindParam(':placeholder', $variable, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 255); 4?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
int
PDO::PARAM_INPUT_OUTPUTは、プリペアドステートメントでINOUTパラメータを指定するための整数定数です。INOUTパラメータは、関数に渡す際に入力値として使用され、関数実行後にその値が更新されて返されることを示します。
サンプルコード
PDO::PARAM_INPUT_OUTPUT でINOUTパラメータをバインドする
1<?php 2 3/** 4 * PDO::PARAM_INPUT_OUTPUT 定数を使用して、ストアドプロシージャのINOUTパラメータをバインドする例。 5 * 6 * このコードは、INOUTパラメータを持つストアドプロシージャがデータベースに存在することを前提としています。 7 * 例として、MySQLで以下のようなプロシージャが作成されていることを想定しています。 8 * 9 * SQL (MySQL): 10 * CREATE PROCEDURE increment_and_return(INOUT val INT) 11 * BEGIN 12 * SET val = val + 10; 13 * END; 14 */ 15function demonstratePdoParamInputOutput(): void 16{ 17 // データベース接続設定 18 // 実際の環境に合わせて 'localhost', 'test_db', 'root', 'password' を変更してください。 19 $dsn = 'mysql:host=localhost;dbname=test_db;charset=utf8mb4'; 20 $user = 'root'; 21 $password = 'password'; 22 23 try { 24 // PDOオブジェクトの作成 25 // エラーモードを例外に設定し、プリペアドステートメントのエミュレーションを無効化することが推奨されます。 26 $pdo = new PDO($dsn, $user, $password, [ 27 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 28 PDO::ATTR_EMULATE_PREPARES => false, 29 ]); 30 31 echo "データベースに接続しました。\n"; 32 33 // 呼び出すストアドプロシージャの名前 34 $procedureName = 'increment_and_return'; 35 36 // INOUTパラメータの初期値を準備 37 $initialValue = 5; 38 // この変数にストアドプロシージャからの結果が格納されます 39 $outputValue = $initialValue; 40 41 echo "INOUTパラメータの初期値: " . $initialValue . "\n"; 42 43 // ストアドプロシージャの呼び出しを準備 44 // ストアドプロシージャの呼び出し構文はデータベースシステムによって異なる場合があります。 45 $stmt = $pdo->prepare("CALL {$procedureName}(?)"); 46 47 // パラメータをバインド 48 // 1番目のプレースホルダに $outputValue 変数をバインドします。 49 // PDO::PARAM_INT はパラメータが整数型であることを示します。 50 // PDO::PARAM_INPUT_OUTPUT は、このパラメータが入力と出力の両方であることをPDOに伝えます。 51 // 第4引数の '4' は、INOUTパラメータの最大長 (INT型の場合のバイト数) を指定します。 52 $stmt->bindParam(1, $outputValue, PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUT, 4); 53 54 // ストアドプロシージャを実行 55 $stmt->execute(); 56 57 // ストアドプロシージャ実行後、$outputValue に結果が格納されます 58 echo "ストアドプロシージャ実行後の値: " . $outputValue . "\n"; 59 60 } catch (PDOException $e) { 61 // データベース関連のエラーが発生した場合の処理 62 echo "データベースエラー: " . $e->getMessage() . "\n"; 63 exit(1); 64 } catch (Exception $e) { 65 // その他の予期せぬエラーが発生した場合の処理 66 echo "予期せぬエラー: " . $e->getMessage() . "\n"; 67 exit(1); 68 } 69} 70 71// 関数の実行 72demonstratePdoParamInputOutput();
このPHPコードは、データベースのストアドプロシージャでINOUT(入力と出力の両方)として機能するパラメータを扱う方法を示しています。特にPDO::PARAM_INPUT_OUTPUT定数の使用例を通じて、PHPからストアドプロシージャと双方向にデータをやり取りする仕組みを学ぶことができます。
まず、PDO拡張機能を用いてデータベースに接続します。その後、呼び出すストアドプロシージャの名前と、INOUTパラメータの初期値を格納する変数を準備します。この変数には、ストアドプロシージャが実行された後、変更された結果が格納されることになります。
重要なのは、PDO::prepareでストアドプロシージャの呼び出しを準備し、PDO::bindParamでパラメータをバインドする部分です。PDO::bindParamの第3引数には、データの型を示すPDO::PARAM_INTと、このパラメータが入力と出力の両方に使われることを示すPDO::PARAM_INPUT_OUTPUTをビットOR演算子で組み合わせて指定します。これにより、PDOはバインドされた変数をストアドプロシージャへの入力として渡し、プロシージャの実行結果として同じ変数に変更された値を書き戻すようになります。PDO::PARAM_INPUT_OUTPUT定数自体には引数はなく、内部的には整数値(int)を返します。また、第4引数でINOUTパラメータの最大長を指定する必要があります。
最後にexecute()を実行すると、ストアドプロシージャがデータベースで実行され、バインドした変数$outputValueにはプロシージャ内で処理された最終的な値が反映されます。この方法により、ストアドプロシージャの強力な機能とPHPアプリケーションを連携させることが可能になります。
このサンプルコードは、ストアドプロシージャのINOUTパラメータを扱う際に、PDO::PARAM_INPUT_OUTPUT定数をbindParamメソッドで使用する例です。コードを実行する前に、データベースにincrement_and_returnのようなストアドプロシージャが事前に作成されている必要があります。
bindParamの呼び出しでは、PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUTのようにデータ型とINPUT_OUTPUTフラグを組み合わせて指定し、さらに第4引数でバインドする変数の最大長を正しく指定することが重要です。
データベース接続設定($dsn, $user, $password)は、必ずご自身の環境に合わせて変更してください。PDOオブジェクト作成時にATTR_ERRMODEをERRMODE_EXCEPTIONに、ATTR_EMULATE_PREPARESをfalseに設定することで、エラーを例外として扱い、より安全で正確な処理を実現できます。ストアドプロシージャの呼び出し構文は、使用するデータベースシステムによって異なる場合がありますのでご注意ください。
PDO::PARAM_INPUT_OUTPUT と PDO::PARAM_INT の使い方
1<?php 2 3/** 4 * PDO::PARAM_INPUT_OUTPUT 定数の使用例。 5 * 6 * この関数は、PDOStatement::bindParam() メソッドで 7 * データベースのストアドプロシージャにおけるINOUTパラメータを 8 * バインドする際に PDO::PARAM_INPUT_OUTPUT がどのように使われるかを示します。 9 * 通常、データ型定数(例: PDO::PARAM_INT)と組み合わせて指定します。 10 */ 11function demonstratePdoParamInputOutput(): void 12{ 13 // PDO::PARAM_INPUT_OUTPUT と PDO::PARAM_INT の定数値を出力します。 14 // PDO::PARAM_INPUT_OUTPUT はINOUTパラメータの方向を示し、 15 // PDO::PARAM_INT はデータの型(整数)を示します。 16 echo "PDO::PARAM_INPUT_OUTPUT の値: " . PDO::PARAM_INPUT_OUTPUT . PHP_EOL; 17 echo "PDO::PARAM_INT の値: " . PDO::PARAM_INT . PHP_EOL; 18 19 // インメモリSQLiteデータベースへの接続を試みます。 20 // 実際のアプリケーションでは、ストアドプロシージャをサポートする 21 // MySQLやPostgreSQLなどのデータベースに接続します。 22 try { 23 $pdo = new PDO('sqlite::memory:'); 24 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 25 26 // SQLiteはストアドプロシージャを直接サポートしないため、 27 // この例ではダミーのSELECT文を使用し、bindParamの概念を示します。 28 // 実際のストアドプロシージャでは、INOUTパラメータの値が 29 // データベース側で更新され、PHP側でその更新された値を取得できます。 30 $stmt = $pdo->prepare("SELECT ? as output_value_from_db"); 31 32 // INOUTパラメータとしてバインドする変数を準備します。 33 $parameterValue = 100; 34 echo "バインド前の変数 'parameterValue': " . $parameterValue . PHP_EOL; 35 36 // PDO::PARAM_INT と PDO::PARAM_INPUT_OUTPUT を論理和 (|) で組み合わせて指定します。 37 // これにより、整数型のINOUTパラメータとして変数をバインドすることを示します。 38 // 第4引数の「4」は最大長を示し、文字列型の場合に重要ですが、bindParamのシグネチャに合わせます。 39 $stmt->bindParam(1, $parameterValue, PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUT, 4); 40 41 // SQL文(またはストアドプロシージャ)を実行します。 42 $stmt->execute(); 43 44 // 実際のストアドプロシージャが実行された場合、 45 // ここで $parameterValue の値がプロシージャ内で更新された値に変わります。 46 // SQLiteのSELECT文では値は変更されませんが、概念を示すために表示します。 47 echo "実行後の変数 'parameterValue' (ストアドプロシージャで更新される可能性あり): " . $parameterValue . PHP_EOL; 48 49 // SELECT文の結果を取得し、表示します。 50 $result = $stmt->fetch(PDO::FETCH_ASSOC); 51 echo "SQL実行結果: " . var_export($result, true) . PHP_EOL; 52 53 } catch (PDOException $e) { 54 // データベース接続または操作中にエラーが発生した場合 55 echo "データベースエラー: " . $e->getMessage() . PHP_EOL; 56 } 57} 58 59// サンプルコードの関数を実行します。 60demonstratePdoParamInputOutput();
PHPのPDO::PARAM_INPUT_OUTPUT定数は、データベースのストアドプロシージャにおいて、入力と出力の両方に使用される「INOUTパラメータ」を扱う際に利用されます。この定数自体に引数はなく、内部的に整数値(int)を返します。
通常、この定数はPDOStatement::bindParam()メソッドの引数として使用され、パラメータのデータ型を示す他の定数(例えば、整数型を表すPDO::PARAM_INTなど)と論理和(|)で組み合わせて指定されます。これにより、指定した変数がデータベースのストアドプロシージャに初期値として渡され、プロシージャ内でその変数の値が更新された場合、PHP側で更新後の値を取得できるようになります。
サンプルコードでは、PDO::PARAM_INPUT_OUTPUTとPDO::PARAM_INTの定数値を出力し、それぞれの役割を示しています。ストアドプロシージャを直接サポートしないSQLiteのインメモリデータベースを使用しているため、ダミーのSELECT文でbindParamの概念を説明しています。bindParamによって変数$parameterValueをINOUTパラメータとしてバインドし、execute後にその変数が(概念的に)更新される様子を示しており、INOUTパラメータがどのように機能するかを理解するのに役立ちます。
PDO::PARAM_INPUT_OUTPUTは、ストアドプロシージャのINOUT(入出力)パラメータにのみ使用します。データ型定数(例: PDO::PARAM_INT)と論理和(|)で組み合わせて使います。bindParam()でバインドした変数は、プロシージャ実行後にDB側で値が更新されるため、実行後の値を確認しましょう。MySQLなどストアドプロシージャ対応DBでのみ利用でき、SQLiteは概念実証用です。bindParam()の第4引数は文字列型で重要です。