【PHP8.x】PDO::exec()メソッドの使い方
execメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
execメソッドは、PHPのデータベースアクセスインターフェースであるPDO(PHP Data Objects)拡張機能に属するPDOクラスのメソッドで、データベースに対してSQL文を実行するメソッドです。主にINSERT、UPDATE、DELETEといった、結果セット(データの集合)を返さないタイプのSQL文を実行する際に利用されます。例えば、データベースに新しいデータを挿入したり、既存のデータを更新・削除したり、あるいはテーブルを作成・変更したりするなどの操作に適しています。
このメソッドは、SQL文の実行が成功した場合、その操作によって変更または影響を受けた行数を整数値で返します。データベースへの接続に失敗した場合や、不正なSQL文が渡された場合など、エラーが発生した際には、PDOのエラーモード設定に応じてブール値falseを返すか、PDOException例外をスローしてエラーを通知します。
重要な注意点として、execメソッドはSELECT文のようにデータベースからデータセットを取得する目的には使用できません。結果セットを扱う場合は、PDO::queryメソッドまたはPDO::prepareメソッドを使用してください。また、セキュリティ上の理由から、ユーザーからの入力データを含むSQL文を実行する際には、SQLインジェクションのリスクを避けるため、PDO::prepareメソッドとパラメータバインディングの利用が強く推奨されます。execメソッドは、主に固定のSQL文や、完全に信頼できるソースからのSQL文を実行する場合に利用するのが安全な方法です。
構文(syntax)
1<?php 2 3// データベース接続情報(ご自身の環境に合わせて設定してください) 4$dsn = 'mysql:host=localhost;dbname=test_db;charset=utf8mb4'; 5$user = 'your_username'; 6$password = 'your_password'; 7 8// PDOオブジェクトを生成 9$pdo = new PDO($dsn, $user, $password); 10 11// 実行するSQL文を定義(SELECT文には適していません。INSERT, UPDATE, DELETEなどを使用します) 12$sql = "INSERT INTO users (name, email) VALUES ('山田太郎', 'yamada.t@example.com');"; 13 14// PDO::exec() メソッドを呼び出し、SQL文を実行 15// 戻り値は、成功した場合は影響を受けた行数(int)、失敗した場合はfalse 16$affectedRows = $pdo->exec($sql); 17 18// 実行結果を確認 19if ($affectedRows !== false) { 20 echo "SQL実行成功。影響を受けた行数: " . $affectedRows . "件\n"; 21} else { 22 echo "SQL実行失敗。\n"; 23 // 詳細なエラー情報は $pdo->errorInfo() で取得できますが、ここでは省略します。 24} 25 26?>
引数(parameters)
string $statement
- string $statement: 実行するSQL文またはその他のデータベースコマンドを指定する文字列
戻り値(return)
int|false
PDO::exec() メソッドは、SQL 文を実行し、影響を受けた行数を整数で返します。SQL 文の実行に失敗した場合は false を返します。
サンプルコード
PHP PDO exec でSQLを実行する
1<?php 2 3/** 4 * PDO::exec メソッドの使用例を示します。 5 * このメソッドは、結果セットを返さない SQL ステートメント (例: CREATE TABLE, INSERT, UPDATE, DELETE) を実行するのに使用されます。 6 * 7 * この例では、設定が簡単なインメモリ SQLite データベースを使用しています。 8 */ 9function runPdoExecExample(): void 10{ 11 // データベース接続情報 12 // "sqlite::memory:" を使用すると、ディスクにファイルを作成せず、メモリ上に一時的なデータベースを作成します。 13 // スクリプトの実行が終了すると、このデータベースは消滅します。 14 $dsn = 'sqlite::memory:'; 15 $username = null; // SQLite の場合、通常ユーザー名とパスワードは不要です 16 $password = null; 17 18 try { 19 // 1. PDO オブジェクトを作成し、データベースに接続します。 20 // PDO::ATTR_ERRMODE を PDO::ERRMODE_EXCEPTION に設定することで、 21 // SQL エラーが発生した場合に PDOException がスローされるようになります。 22 $pdo = new PDO($dsn, $username, $password, [ 23 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 24 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, 25 ]); 26 27 echo "データベースに接続しました。\n"; 28 29 // 2. テーブルを作成する SQL ステートメントを実行します。 30 // PDO::exec は、CREATE TABLE のような DDL (データ定義言語) ステートメントの場合、 31 // 通常 0 を返します (成功した行数がないため)。 32 $createTableSql = " 33 CREATE TABLE IF NOT EXISTS users ( 34 id INTEGER PRIMARY KEY AUTOINCREMENT, 35 name TEXT NOT NULL, 36 email TEXT UNIQUE NOT NULL 37 ); 38 "; 39 $result = $pdo->exec($createTableSql); 40 41 if ($result === false) { 42 // PDO::ERRMODE_EXCEPTION の場合、通常このブロックはSQLエラーでは実行されません 43 echo "テーブル 'users' の作成中にエラーが発生しました。\n"; 44 } else { 45 echo "テーブル 'users' を作成しました (または既に存在していました)。\n"; 46 } 47 48 // 3. データを挿入する SQL ステートメントを実行します。 49 // PDO::exec は、INSERT, UPDATE, DELETE のような DML (データ操作言語) ステートメントの場合、 50 // 影響を受けた行数を返します。 51 $insertSql1 = "INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');"; 52 $affectedRows1 = $pdo->exec($insertSql1); 53 54 if ($affectedRows1 === false) { 55 echo "Alice のデータ挿入中にエラーが発生しました。\n"; 56 } else { 57 echo "Alice を挿入しました。影響を受けた行数: " . $affectedRows1 . "\n"; 58 } 59 60 // 4. 別のデータを挿入する SQL ステートメントを実行します。 61 $insertSql2 = "INSERT INTO users (name, email) VALUES ('Bob', 'bob@example.com');"; 62 $affectedRows2 = $pdo->exec($insertSql2); 63 64 if ($affectedRows2 === false) { 65 echo "Bob のデータ挿入中にエラーが発生しました。\n"; 66 } else { 67 echo "Bob を挿入しました。影響を受けた行数: " . $affectedRows2 . "\n"; 68 } 69 70 // 5. データを更新する SQL ステートメントを実行します。 71 $updateSql = "UPDATE users SET name = 'Alicia' WHERE name = 'Alice';"; 72 $updatedRows = $pdo->exec($updateSql); 73 74 if ($updatedRows === false) { 75 echo "Alice のデータ更新中にエラーが発生しました。\n"; 76 } else { 77 echo "'Alice' を 'Alicia' に更新しました。影響を受けた行数: " . $updatedRows . "\n"; 78 } 79 80 } catch (PDOException $e) { 81 // PDO 関連のエラー(データベース接続失敗、SQL エラーなど)を捕捉します。 82 echo "データベースエラーが発生しました: " . $e->getMessage() . "\n"; 83 } catch (Exception $e) { 84 // その他の予期せぬエラーを捕捉します。 85 echo "予期せぬエラーが発生しました: " . $e->getMessage() . "\n"; 86 } 87} 88 89// 上記のサンプル関数を実行します。 90runPdoExecExample(); 91 92?>
PDO::execメソッドは、PHPでデータベースに対してSQLステートメントを実行する際に使用する機能です。主に、結果セットを返さないタイプのSQL文、例えばテーブルを作成するCREATE TABLE、データを追加するINSERT、更新するUPDATE、削除するDELETEなどのDML(データ操作言語)やDDL(データ定義言語)のステートメントに利用されます。
引数には、実行したいSQL文を文字列として渡します。メソッドが成功した場合、戻り値は実行されたSQL文によって影響を受けた行数を整数で返します。例えば、INSERTやUPDATE文では、実際に処理されたレコードの数が戻り値となります。CREATE TABLEのようなデータベース構造を変更するSQL文の場合、通常は0が返されます。もし実行に失敗した場合はfalseを返しますが、PDOのエラーモードをPDO::ERRMODE_EXCEPTIONに設定している場合、SQLエラーはPDOExceptionとして捕捉されることが一般的です。
このサンプルコードでは、メモリ上に一時的なデータベースを作成するSQLiteを使用しているため、手軽にPDO::execメソッドの動作を確認できます。テーブルの作成、データの挿入、更新といった各操作でPDO::execがどのように利用され、その結果としてどのような戻り値が得られるかを具体的に示しています。
PDO::execは、テーブルの作成やデータの挿入、更新、削除など、結果セットを返さないSQLステートメントを実行するために使用します。データ取得(SELECT)には不向きなメソッドです。成功時には影響を受けた行数が整数で返され、失敗時にはfalseが返されます。ただし、テーブル作成のようなデータ定義言語(DDL)文では、成功しても通常0が返される点に注意してください。
最も重要な点として、ユーザーからの入力値をSQLに直接含めるような処理では、PDO::execを絶対に使用しないでください。 このメソッドはSQLインジェクション攻撃のリスクが高いため、ユーザー入力を含む場合は必ずPDO::prepareとPDOStatement::executeを使ったプリペアドステートメントを利用し、セキュリティを確保してください。また、PDO::ATTR_ERRMODEをPDO::ERRMODE_EXCEPTIONに設定することで、SQLエラーをPDOExceptionとして捕捉し、堅牢なエラーハンドリングを行うことが推奨されます。
PHP PDO::exec でSQL実行と行数を取得する
1<?php 2 3/** 4 * PDO::exec メソッドの使用例 5 * 6 * PDO::exec は、結果セットを返さない SQL ステートメント(例: CREATE TABLE, INSERT, UPDATE, DELETE)を実行し、 7 * 影響を受けた行数を返します。エラーが発生した場合は false を返します。 8 * 通常、PDO::setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) を設定し、 9 * 例外でエラーを処理することが推奨されます。 10 */ 11try { 12 // 1. データベースへの接続 13 // SQLite のインメモリデータベースを使用しています。 14 // ':memory:' を使用すると、データはメモリ上に一時的に作成され、スクリプト終了時に破棄されます。 15 // これはテストや簡単なサンプルに適しています。 16 $pdo = new PDO('sqlite::memory:'); 17 18 // PDO のエラーモードを例外に設定します。 19 // これにより、SQL エラーが発生した場合に PDOException がスローされ、try-catch ブロックで捕捉できます。 20 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 21 22 echo "データベースに接続しました。\n\n"; 23 24 // 2. PDO::exec を使用してテーブルを作成 25 // CREATE TABLE 文は結果セットを返さないため、exec を使用します。 26 $createTableSql = " 27 CREATE TABLE IF NOT EXISTS users ( 28 id INTEGER PRIMARY KEY AUTOINCREMENT, 29 name VARCHAR(50) NOT NULL, 30 email VARCHAR(100) UNIQUE 31 ); 32 "; 33 // exec は成功した場合に影響を受けた行数(CREATE TABLE の場合は通常0)を、 34 // 失敗した場合は false を返します。 35 $result = $pdo->exec($createTableSql); 36 37 // エラーモードが例外に設定されているため、通常は false をチェックする前に例外がスローされます。 38 // しかし、exec メソッドの戻り値の型が int|false であるため、false の可能性も考慮してチェックします。 39 if ($result !== false) { 40 echo "テーブル 'users' の作成を試みました。\n"; 41 } else { 42 echo "テーブル 'users' の作成に失敗しました。\n"; 43 } 44 echo "\n"; 45 46 // 3. PDO::exec を使用してデータを挿入 47 // INSERT 文も結果セットを返さないため、exec を使用します。 48 $insertSql = "INSERT INTO users (name, email) VALUES ('John Doe', 'john.doe@example.com');"; 49 $affectedRows = $pdo->exec($insertSql); 50 51 if ($affectedRows !== false) { 52 echo "ユーザー 'John Doe' を挿入しました。影響を受けた行数: " . $affectedRows . "\n"; 53 } else { 54 echo "ユーザー 'John Doe' の挿入に失敗しました。\n"; 55 } 56 57 $insertSql2 = "INSERT INTO users (name, email) VALUES ('Jane Smith', 'jane.smith@example.com');"; 58 $affectedRows2 = $pdo->exec($insertSql2); 59 60 if ($affectedRows2 !== false) { 61 echo "ユーザー 'Jane Smith' を挿入しました。影響を受けた行数: " . $affectedRows2 . "\n"; 62 } else { 63 echo "ユーザー 'Jane Smith' の挿入に失敗しました。\n"; 64 } 65 echo "\n"; 66 67 // 4. PDO::exec を使用してデータを更新 68 // UPDATE 文も結果セットを返さないため、exec を使用します。 69 $updateSql = "UPDATE users SET name = 'Johnny Doe' WHERE email = 'john.doe@example.com';"; 70 $affectedRows3 = $pdo->exec($updateSql); 71 72 if ($affectedRows3 !== false) { 73 echo "ユーザー 'John Doe' を 'Johnny Doe' に更新しました。影響を受けた行数: " . $affectedRows3 . "\n"; 74 } else { 75 echo "ユーザー 'John Doe' の更新に失敗しました。\n"; 76 } 77 echo "\n"; 78 79 // 5. PDO::exec を使用してデータを削除 80 // DELETE 文も結果セットを返さないため、exec を使用します。 81 $deleteSql = "DELETE FROM users WHERE email = 'jane.smith@example.com';"; 82 $affectedRows4 = $pdo->exec($deleteSql); 83 84 if ($affectedRows4 !== false) { 85 echo "ユーザー 'Jane Smith' を削除しました。影響を受けた行数: " . $affectedRows4 . "\n"; 86 } else { 87 echo "ユーザー 'Jane Smith' の削除に失敗しました。\n"; 88 } 89 echo "\n"; 90 91} catch (PDOException $e) { 92 // データベース関連のエラーを捕捉します。 93 echo "データベースエラーが発生しました: " . $e->getMessage() . "\n"; 94} catch (Exception $e) { 95 // その他の予期せぬエラーを捕捉します。 96 echo "一般エラーが発生しました: " . $e->getMessage() . "\n"; 97} 98 99// スクリプト終了時にデータベース接続は自動的に閉じられます。 100?>
PHPのPDO::execメソッドは、データベースに対して結果セット(データ一覧)を返さないSQLステートメントを実行するために使用します。具体的には、テーブルの作成(CREATE TABLE)や、データの挿入(INSERT)、更新(UPDATE)、削除(DELETE)といった操作を行う際に利用されます。
このメソッドは、実行したいSQLステートメントをstring $statementとして引数に取ります。SQLの実行が成功すると、その操作によってデータベース上で影響を受けた行数を示す整数値がint型で返されます(例えばCREATE TABLEの場合は通常0行です)。もしデータベースの操作中にエラーが発生した場合は、falseが戻り値となります。
サンプルコードでは、まずSQLiteのインメモリデータベースに接続し、PDO::setAttributeを使ってエラー発生時にPDOExceptionをスローするように設定しています。これにより、try-catchブロックでデータベース関連のエラーを効果的に処理できます。その後、PDO::execを利用してusersテーブルを作成し、データの挿入、更新、削除といった一連の操作を実行しています。各操作の後に戻り値を確認し、影響を受けた行数や成功・失敗のメッセージを表示することで、PDO::execの挙動を理解しやすくしています。
PDO::execは、テーブル作成やデータ挿入・更新・削除など、結果セットを返さないSQL文を実行する際に使用します。成功すると影響を受けた行数が数値で、失敗するとfalseが返ります。エラーモードをPDO::ERRMODE_EXCEPTIONに設定すると、SQLエラー時にPDOExceptionがスローされるため、try-catchでの例外処理が効果的です。特に重要なのは、PDO::execにユーザーからの入力を直接含んだSQL文を渡すと、SQLインジェクション攻撃のリスクがあります。動的な値を含むSQL文を実行する場合は、セキュリティ確保のため、必ずプレースホルダを使用するPDO::prepareとPDOStatement::executeメソッドを利用してください。SELECT文には適していません。