【PHP8.x】SQLite3::exec()メソッドの使い方
execメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
execメソッドは、SQLite3データベースに対してSQLステートメントを実行するメソッドです。このメソッドは、主に結果セット(問い合わせ結果のデータ)を返さないタイプのSQLクエリを実行する際に使用されます。例えば、データベース内に新しいテーブルを作成するCREATE TABLE文、データを追加するINSERT文、既存のデータを更新するUPDATE文、または不要なデータを削除するDELETE文などが挙げられます。execメソッドは、実行したいSQLステートメントの文字列を引数として受け取ります。SQLステートメントが正常に実行された場合はブール値のtrueを返し、何らかのエラーが発生して実行に失敗した場合はfalseを返します。複数のSQLステートメントをセミコロンで区切って一度に実行することも可能です。ただし、データをデータベースから取得するSELECT文のように、結果セットを伴うクエリを実行する目的では使用できませんのでご注意ください。そのような場合は、queryメソッドやquerySingleメソッドをご利用ください。このメソッドを使用する際は、戻り値を確認し、データベース操作が意図通りに成功したかどうかを適切に処理することが重要です。
構文(syntax)
1<?php 2$db = new SQLite3('mydatabase.db'); 3$sql = 'CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)'; 4$db->exec($sql); 5$db->close(); 6?>
引数(parameters)
string $query
- string $query: 実行するSQLクエリを指定する文字列
戻り値(return)
bool
SQLite3::exec メソッドは、SQL文を実行し、その成功・失敗を示す真偽値(bool)を返します。成功した場合は true、失敗した場合は false を返します。
サンプルコード
PHP SQLite3::exec() でテーブル作成・データ挿入する
1<?php 2 3/** 4 * SQLite3::exec() メソッドの利用例 5 * 6 * このスクリプトは、SQLite3 データベースを作成し、 7 * SQLite3::exec() メソッドを使用してテーブル作成とデータ挿入を行います。 8 * exec() メソッドは、結果セットを返さない DDL (データ定義言語) や DML (データ操作言語) クエリの実行に適しています。 9 */ 10 11// データベースファイル名を定義します。 12// このファイルが存在しない場合は新しく作成され、存在する場合は開かれます。 13$dbFileName = 'my_database.db'; 14 15// データベース接続を開きます。 16// エラーが発生した場合は例外がスローされます。 17try { 18 $db = new SQLite3($dbFileName); 19 echo "データベース '" . $dbFileName . "' に接続しました。\n"; 20} catch (Exception $e) { 21 die("データベース接続に失敗しました: " . $e->getMessage() . "\n"); 22} 23 24// -------------------------------------------------------------------------------- 25// SQLite3::exec() を使ったテーブル作成 (DDL) の例 26// -------------------------------------------------------------------------------- 27 28// 'users' テーブルを作成するSQLクエリです。 29// IF NOT EXISTS を使用することで、テーブルが既に存在する場合にエラーになるのを防ぎます。 30// ID は自動増分される主キー、name は必須のテキストフィールドです。 31$createTableQuery = 'CREATE TABLE IF NOT EXISTS users ( 32 id INTEGER PRIMARY KEY AUTOINCREMENT, 33 name TEXT NOT NULL 34)'; 35 36// exec() メソッドを使ってテーブル作成クエリを実行します。 37// 成功した場合は true、失敗した場合は false を返します。 38if ($db->exec($createTableQuery)) { 39 echo "テーブル 'users' が正常に作成または既に存在します。\n"; 40} else { 41 // 失敗した場合、lastErrorMsg() でエラーメッセージを取得できます。 42 echo "テーブル作成に失敗しました: " . $db->lastErrorMsg() . "\n"; 43 $db->close(); // エラーが発生したため、データベース接続を閉じて終了します。 44 exit(1); 45} 46 47// -------------------------------------------------------------------------------- 48// SQLite3::exec() を使ったデータ挿入 (DML) の例 49// -------------------------------------------------------------------------------- 50 51// 'users' テーブルにデータを挿入するSQLクエリです。 52$insertDataQuery1 = "INSERT INTO users (name) VALUES ('Alice')"; 53$insertDataQuery2 = "INSERT INTO users (name) VALUES ('Bob')"; 54 55// exec() メソッドを使ってデータを挿入します。 56if ($db->exec($insertDataQuery1)) { 57 echo "データ 'Alice' が正常に挿入されました。\n"; 58} else { 59 echo "データ挿入に失敗しました (Alice): " . $db->lastErrorMsg() . "\n"; 60} 61 62if ($db->exec($insertDataQuery2)) { 63 echo "データ 'Bob' が正常に挿入されました。\n"; 64} else { 65 echo "データ挿入に失敗しました (Bob): " . $db->lastErrorMsg() . "\n"; 66} 67 68// -------------------------------------------------------------------------------- 69// 注意点: SELECT クエリには exec() を使用しないでください。 70// exec() は結果セットを返さないため、SELECT クエリでデータを取得するには 71// query() や querySingle() メソッドを使用する必要があります。 72// 例: 73// $result = $db->query('SELECT id, name FROM users'); 74// while ($row = $result->fetchArray(SQLITE3_ASSOC)) { 75// echo "ID: " . $row['id'] . ", Name: " . $row['name'] . "\n"; 76// } 77// -------------------------------------------------------------------------------- 78 79// データベース接続を閉じます。 80// これにより、開かれているリソースが解放されます。 81$db->close(); 82echo "データベース接続を閉じました。\n"; 83 84// スクリプトの実行が正常に完了したことを示します。 85exit(0);
PHPのSQLite3::exec()メソッドは、SQLiteデータベースに対して、結果を返さないSQLクエリを実行するために使用します。具体的には、テーブルの作成や変更(DDL: データ定義言語)、またはデータの挿入、更新、削除(DML: データ操作言語)などの操作に適しています。
このメソッドは、引数として実行したいSQLクエリの文字列を受け取ります。クエリの実行が成功した場合はtrueを、失敗した場合はfalseを戻り値として返します。もし実行が失敗した場合、SQLite3::lastErrorMsg()メソッドを使用することで、より詳細なエラーメッセージを取得し、問題の原因を特定できます。
サンプルコードでは、まずmy_database.dbというSQLiteデータベースファイルに接続します。その後、exec()メソッドを用いてCREATE TABLE文を実行し、usersテーブルを作成しています。さらに、INSERT INTO文で複数のユーザーデータをusersテーブルに挿入する例も示されています。
重要な注意点として、exec()メソッドはデータを取得するSELECTクエリには使用できません。データを参照する場合は、SQLite3::query()やSQLite3::querySingle()といった別のメソッドを利用する必要があります。このように、exec()はデータベースの構造を定義したり、データを変更したりする際に非常に便利なメソッドです。
SQLite3::exec()メソッドは、テーブル作成やデータ挿入・更新・削除など、結果セットを返さないSQLクエリ専用です。データを取得するSELECT文には使えませんので、その際はquery()やquerySingle()を利用してください。
クエリ実行が失敗するとfalseを返すため、必ず戻り値を確認し、$db->lastErrorMsg()でエラー詳細を取得して適切に処理することが重要です。
ユーザーからの入力をSQLクエリに直接組み込むと、SQLインジェクションというセキュリティ上の脆弱性につながる危険性があります。安全のため、SQLite3::prepare()によるプリペアドステートメントの利用を強く推奨します。
データベース接続は、処理の終了時に$db->close()を呼び出し、開かれたリソースを忘れずに閉じてください。
PHP SQLite3::exec 非同期実行の基本
1<?php 2 3/** 4 * SQLite3::exec の基本的な同期実行と、PHPで擬似的な非同期実行(バックグラウンドプロセス)を行うサンプルコード。 5 * 6 * このスクリプトは、2つの実行モードを持ちます。 7 * 1. メインプロセス: 同期処理の実行例を示し、その後、自身をバックグラウンドプロセスとして起動して非同期処理を実行します。 8 * 2. 非同期ワーカープロセス: バックグラウンドで起動され、SQLite3::exec を同期的に実行し、結果をログに記録します。 9 * 10 * コマンドラインから `php your_script_name.php` で実行してください。 11 */ 12 13// データベースファイルのパスを定義 14define('DB_PATH', __DIR__ . '/sample.db'); 15// 非同期処理のログファイルのパスを定義 16define('ASYNC_LOG_PATH', __DIR__ . '/async_exec_log.log'); 17 18/** 19 * SQLite3::exec を使ってSQLクエリを同期的に実行します。 20 * クエリが完了するまで処理はブロックされます。 21 * 22 * @param string $query 実行するSQLクエリ文字列 23 * @return bool クエリが成功した場合は true、失敗した場合は false 24 */ 25function executeSqlSync(string $query): bool 26{ 27 try { 28 $db = new SQLite3(DB_PATH); 29 $result = $db->exec($query); 30 $db->close(); 31 return $result; 32 } catch (Exception $e) { 33 // エラーが発生した場合、標準エラーログに出力 34 error_log("同期SQL実行エラー: " . $e->getMessage() . " クエリ: " . $query); 35 return false; 36 } 37} 38 39/** 40 * SQLite3::exec を非同期的に(バックグラウンドプロセスで)実行します。 41 * 42 * この関数は、現在のPHPスクリプト自身を別のプロセスとしてバックグラウンドで起動します。 43 * 起動されたプロセス内で指定されたSQLクエリが同期的に実行され、結果はログファイルに記録されます。 44 * メインプロセスはバックグラウンドプロセスの完了を待ちません。 45 * 46 * @param string $query 実行するSQLクエリ文字列 47 * @return bool バックグラウンドプロセスが正常に起動できた場合は true、それ以外は false 48 */ 49function executeSqlAsync(string $query): bool 50{ 51 // 現在のPHPスクリプトのパスを取得 52 $scriptPath = __FILE__; 53 54 // バックグラウンドプロセスに渡す引数を準備 55 // `mode` を 'async_worker' に設定し、ワーカーとして動作するように指示 56 $args = [ 57 'mode' => 'async_worker', 58 'query' => $query, 59 'db_path' => DB_PATH, 60 'log_path' => ASYNC_LOG_PATH, 61 ]; 62 63 // 引数をJSONエンコードし、シェルコマンドに安全に渡せるようにエスケープ 64 $jsonArgs = escapeshellarg(json_encode($args)); 65 66 // PHP CLIコマンドをバックグラウンドで実行 67 // Unix系OSの場合の例。Windows環境では `start /b php -f ...` のように調整が必要。 68 // `> /dev/null 2>&1 &` は、標準出力と標準エラー出力を破棄し、プロセスをバックグラウンドで実行するための一般的な記述 69 $command = sprintf( 70 'php -f %s %s > /dev/null 2>&1 &', 71 escapeshellarg($scriptPath), 72 $jsonArgs 73 ); 74 75 // `shell_exec` を使用してコマンドを実行 76 // この関数はコマンドの出力を返すが、バックグラウンド実行のため、通常は空文字列が返る 77 shell_exec($command); 78 79 // バックグラウンドプロセスが起動されたと判断し、true を返す 80 // SQLクエリ自体の実行結果は、別途ログファイルで確認する必要がある 81 return true; 82} 83 84// スクリプトが非同期ワーカーとして起動された場合の処理 85// コマンドライン引数 `$argv` を確認し、`async_worker` モードで起動されたか判断 86if (isset($argv[1])) { 87 $decodedArgs = json_decode($argv[1], true); 88 if (json_last_error() === JSON_ERROR_NONE && isset($decodedArgs['mode']) && $decodedArgs['mode'] === 'async_worker') { 89 $query = $decodedArgs['query'] ?? ''; 90 $dbPath = $decodedArgs['db_path'] ?? ''; 91 $logPath = $decodedArgs['log_path'] ?? ''; 92 93 // 必要な引数がない場合はエラーとして終了 94 if (!$query || !$dbPath || !$logPath) { 95 file_put_contents($logPath, date('[Y-m-d H:i:s]') . " [ERROR] 非同期ワーカーの引数が不足しています。\n", FILE_APPEND); 96 exit(1); 97 } 98 99 try { 100 $db = new SQLite3($dbPath); 101 // ここで SQLite3::exec が同期的に実行される 102 $result = $db->exec($query); 103 $db->close(); 104 // 実行結果をログファイルに記録 105 file_put_contents($logPath, date('[Y-m-d H:i:s]') . " [INFO] クエリ実行: \"$query\" - 結果: " . ($result ? '成功' : '失敗') . "\n", FILE_APPEND); 106 exit($result ? 0 : 1); // 成功/失敗に応じて終了コードを設定 107 } catch (Exception $e) { 108 // 例外が発生した場合、エラーをログに記録 109 file_put_contents($logPath, date('[Y-m-d H:i:s]') . " [ERROR] 非同期クエリ実行中に例外: " . $e->getMessage() . " クエリ: \"$query\"\n", FILE_APPEND); 110 exit(1); 111 } 112 } 113} 114 115// --- メインスクリプトの実行部分 --- 116// この部分は、スクリプトがワーカーモードで起動されなかった場合に実行されます。 117 118// 既存のデータベースファイルとログファイルを削除してクリーンアップ 119if (file_exists(DB_PATH)) { 120 unlink(DB_PATH); 121} 122if (file_exists(ASYNC_LOG_PATH)) { 123 unlink(ASYNC_LOG_PATH); 124} 125 126echo "--- SQLite3::exec 同期実行の例 ---\n"; 127// 同期的にテーブルを作成 128if (executeSqlSync('CREATE TABLE IF NOT EXISTS products (id INTEGER PRIMARY KEY, name TEXT, price REAL)')) { 129 echo "同期: 'products' テーブルが正常に作成されました。\n"; 130} else { 131 echo "同期: 'products' テーブルの作成に失敗しました。\n"; 132} 133// 同期的にデータを挿入 134if (executeSqlSync("INSERT INTO products (name, price) VALUES ('ノートPC', 1200.00)")) { 135 echo "同期: 'ノートPC' が正常に挿入されました。\n"; 136} else { 137 echo "同期: 'ノートPC' の挿入に失敗しました。\n"; 138} 139echo "\n"; 140 141 142echo "--- SQLite3::exec 非同期実行の例 (バックグラウンドプロセス経由) ---\n"; 143echo "非同期操作を開始します。結果は '" . ASYNC_LOG_PATH . "' で確認してください。\n"; 144 145// 非同期でテーブルを作成 146executeSqlAsync('CREATE TABLE IF NOT EXISTS orders (id INTEGER PRIMARY KEY, item TEXT, quantity INTEGER)'); 147 148// 非同期でデータを挿入 149executeSqlAsync("INSERT INTO orders (item, quantity) VALUES ('本', 3)"); 150executeSqlAsync("INSERT INTO orders (item, quantity) VALUES ('ペン', 10)"); 151executeSqlAsync("INSERT INTO orders (item, quantity) VALUES ('ノート', 5)"); 152 153echo "メインスクリプトは非同期DB操作の完了を待たずに実行を続行します。\n"; 154 155// 非同期処理がバックグラウンドで実行される間に、メインスクリプトは他の処理を実行できます。 156// ここでは、非同期ログファイルが更新されるのを数秒待つために一時停止します。 157echo "非同期操作が完了するまで待機中 (数秒後にログファイルを確認してください)...\n"; 158sleep(3); // バックグラウンドプロセスが完了するのを少し待つ 159 160echo "非同期操作が開始されました。実際の結果は '" . ASYNC_LOG_PATH . "' を確認してください。\n"; 161 162// ログファイルの内容を表示 (確認用) 163if (file_exists(ASYNC_LOG_PATH)) { 164 echo "\n--- " . ASYNC_LOG_PATH . " の内容 ---\n"; 165 echo file_get_contents(ASYNC_LOG_PATH); 166 echo "-------------------------------------\n"; 167} else { 168 echo "\n" . ASYNC_LOG_PATH . " がまだ見つかりません。処理中かもしれません。\n"; 169}
SQLite3::execメソッドは、PHPでSQLiteデータベースに対してSQLクエリを実行するために使用されます。このメソッドは、引数として文字列で指定されたSQLクエリ$queryを受け取り、そのクエリが正常に実行された場合はtrueを、失敗した場合はfalseをブール値で返します。主にCREATE TABLEやINSERT、UPDATE、DELETEといったデータ操作言語(DML)やデータ定義言語(DDL)のクエリを実行する際に利用されます。
サンプルコードでは、SQLite3::execの実行方法を「同期実行」と「非同期実行」の二つの観点から示しています。同期実行では、executeSqlSync関数が呼び出された際、データベースへの操作が完了するまでプログラムの実行が一時停止し、その結果を受け取ってから次の処理へと進みます。これは一般的な処理の流れです。
一方、非同期実行の例として示されているexecuteSqlAsync関数は、PHPの特性を考慮し、現在のスクリプト自身を新たなプロセスとしてバックグラウンドで起動することで、擬似的な非同期処理を実現しています。この新しいバックグラウンドプロセス内でSQLite3::execが同期的に実行されますが、メインのスクリプトはバックグラウンドプロセスの完了を待たずに自身の処理を続行できます。これにより、データベース操作に時間がかかっても、メインのアプリケーションがブロックされずに動き続けることが可能になります。非同期処理の結果はメインスクリプトには直接返されないため、ログファイルなどを参照して実行状況を確認する必要があります。
このサンプルコードの非同期実行は、shell_execを利用してPHPスクリプトを別のプロセスとしてバックグラウンドで起動する擬似的な手法です。メインプロセスはバックグラウンドの完了を待たないため、実行結果は別途ログファイルで確認する必要があります。shell_execを用いる際は、OSコマンドインジェクションを防ぐため、escapeshellargによる引数エスケープが非常に重要です。また、この方法はOSやサーバー環境に依存し、Windowsではコマンド構文が異なる点に注意してください。SQLite3::execは、ユーザーからの入力を含むSQLクエリを実行する際、SQLインジェクションのリスクがあるため、通常はプリペアドステートメントに対応したメソッドを検討することが推奨されます。非同期処理のエラーはログファイルを確認してデバッグすることになります。