【PHP8.x】openメソッドの使い方

openメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

openメソッドは、SQLite3データベースファイルへの接続を確立するメソッドです。このメソッドは、指定されたファイルパスのデータベースを開き、その後のデータ操作を可能にします。

第一引数には、接続対象となるSQLiteデータベースファイルのパスを文字列で指定します。指定されたパスにファイルが存在しない場合、新規にデータベースファイルが作成されます。

第二引数(オプション)には、データベースのオープンモードを示す整数値を指定できます。例えば、SQLITE3_OPEN_READONLY定数を使用すると読み取り専用でデータベースを開き、SQLITE3_OPEN_READWRITE定数を使用すると読み書き可能なモードで開きます。これらのモードは、SQLITE3_OPEN_CREATE定数と組み合わせて、ファイルが存在しない場合に作成するように指定することも可能です。複数のモードを組み合わせる場合は、ビットOR演算子(|)を使用します。

第三引数(オプション)には、データベースの暗号化に使用するキーを文字列で指定します。暗号化されたデータベースを開く際にこのキーが使用されます。

このメソッドは、データベースのオープンに成功した場合はtrueを、失敗した場合はfalseを返します。データベースとのやり取りを始めるためには、まずこのopenメソッドで接続を確立する必要があります。

構文(syntax)

1new SQLite3(string $filename, int $flags = SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, string $encryptionKey = "")

引数(parameters)

string $filename, int $flags = 6, string $encryptionKey = ''

  • string $filename: SQLiteデータベースファイルへのパスを指定する文字列
  • int $flags = SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE: データベースのオープンモードを指定する整数。デフォルトは読み書き可能で、ファイルが存在しない場合は新規作成します。
  • string $encryptionKey = '': データベースを暗号化する場合に、そのキーを指定する文字列。

戻り値(return)

bool

SQLiteデータベースへの接続に成功した場合は true を、失敗した場合は false を返します。

サンプルコード

PHP SQLite3とOpenSSLで暗号化DBを操作する

1<?php
2
3/**
4 * OpenSSLで生成したキーを使い、暗号化されたSQLite3データベースを操作します。
5 *
6 * このサンプルコードを実行するには、PHPにSQLite3拡張機能がインストールされていること、
7 * かつ、そのSQLite3が暗号化(例: SQLCipher)をサポートするようにコンパイルされている必要があります。
8 * 標準のPHPビルドでは、encryptionKey引数は無視されることがあります。
9 */
10function operateEncryptedDatabase(): void
11{
12    // データベースファイル名
13    $dbFile = 'encrypted_database.sqlite';
14
15    // データベースが既に存在する場合は削除して、毎回クリーンな状態で実行
16    if (file_exists($dbFile)) {
17        unlink($dbFile);
18    }
19
20    try {
21        // 1. OpenSSLを使用して32バイト (256ビット) の暗号化キーを生成
22        // 実際のアプリケーションでは、このキーを安全に保管・管理する必要があります。
23        $encryptionKey = openssl_random_pseudo_bytes(32);
24
25        // 2. SQLite3オブジェクトをインスタンス化
26        $db = new SQLite3();
27
28        // 3. 暗号化キーを指定してデータベースファイルを開く
29        // SQLite3::OPEN_READWRITE | SQLite3::OPEN_CREATE フラグは、
30        // ファイルが存在しない場合は作成し、読み書きモードで開くことを意味します。
31        // 第3引数に暗号化キーを渡します。
32        if (!$db->open($dbFile, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $encryptionKey)) {
33            // openメソッドが失敗した場合、Exceptionをスローします
34            throw new Exception($db->lastErrorMsg());
35        }
36
37        echo "暗号化されたデータベース '{$dbFile}' を正常に開きました。" . PHP_EOL;
38
39        // 4. テーブルの作成
40        $db->exec('CREATE TABLE IF NOT EXISTS messages (id INTEGER PRIMARY KEY, content TEXT NOT NULL)');
41
42        // 5. データの挿入
43        $message = 'This is a secret message.';
44        $stmt = $db->prepare('INSERT INTO messages (content) VALUES (:content)');
45        $stmt->bindValue(':content', $message, SQLITE3_TEXT);
46        $stmt->execute();
47
48        echo "データを挿入しました。" . PHP_EOL;
49
50        // 6. データの取得と表示
51        $result = $db->query('SELECT id, content FROM messages');
52        echo "データベースからデータを取得します..." . PHP_EOL;
53        while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
54            echo "ID: {$row['id']}, Content: {$row['content']}" . PHP_EOL;
55        }
56
57    } catch (Exception $e) {
58        // エラー処理
59        echo "エラーが発生しました: " . $e->getMessage() . PHP_EOL;
60    } finally {
61        // 7. データベース接続を閉じる
62        if (isset($db) && $db instanceof SQLite3) {
63            $db->close();
64            echo "データベース接続を閉じました。" . PHP_EOL;
65        }
66
67        // 8. サンプル用に作成したデータベースファイルをクリーンアップ
68        if (file_exists($dbFile)) {
69            unlink($dbFile);
70            echo "データベースファイルを削除しました。" . PHP_EOL;
71        }
72    }
73}
74
75// 関数を実行
76operateEncryptedDatabase();

このPHPサンプルコードは、SQLite3クラスのopenメソッドを使い、暗号化されたSQLiteデータベースを操作する方法を示します。

openメソッドは、指定されたデータベースファイルへの接続を開くためのものです。第1引数にデータベースのファイル名を、第2引数にファイルのオープンモードを指定するフラグを渡します。この例では、ファイルがなければ新規作成し、読み書き可能なモードで開くように設定しています。

このコードの最大の特徴は、openメソッドの第3引数に暗号化キーを指定している点です。事前にopenssl_random_pseudo_bytes関数で生成したキーを渡すことで、データベースファイル全体が暗号化されます。これにより、正しいキーがなければファイルの中身を読み取ることはできません。

openメソッドの戻り値は真偽値(bool)です。接続に成功した場合はtrueを、失敗した場合はfalseを返します。サンプルコードでは、falseが返された場合に例外を発生させてエラー処理を行っています。データベースを開いた後は、テーブル作成やデータの追加・取得といった通常の操作が可能です。

なお、この暗号化機能を利用するには、PHPのSQLite3拡張機能がSQLCipherなど暗号化をサポートする形でビルドされている必要があります。

このサンプルコードの暗号化機能は、PHPのSQLite3拡張が暗号化(例: SQLCipher)をサポートするよう特別にコンパイルされている環境でのみ動作します。標準のPHP環境では、openメソッドの第3引数にキーを渡しても無視され、データベースは暗号化されない点に注意が必要です。また、実際のアプリケーションでは、データベースに再接続するために暗号化キーを安全な場所に保管し、適切に管理する必要があります。サンプルコードのように毎回キーを生成すると、以前のデータにはアクセスできなくなります。openメソッドは失敗時にfalseを返すため、必ず戻り値を確認し、エラー処理を記述することが重要です。

PHP SQLite3 で openssl_encrypt を使用してデータを暗号化・復号する

1<?php
2
3declare(strict_types=1);
4
5/**
6 * SQLite3データベースに、openssl_encryptを使用して暗号化したデータを格納するサンプルクラス。
7 *
8 * このコードは、SQLite3::openの第3引数 $encryptionKey を使用しません。
9 * 標準のPHPにバンドルされているSQLite3ライブラリでは、データベースファイル自体の
10 * 暗号化はサポートされていないためです。
11 * 代わりに、データベースに格納する「内容」を暗号化する方法を示します。
12 */
13final class EncryptedDatabaseHandler
14{
15    /** @var string データベースファイル名 */
16    private const DB_FILENAME = 'secure_data.sqlite';
17
18    /** @var string 暗号化方式 */
19    private const ENCRYPTION_METHOD = 'aes-256-cbc';
20
21    /** @var SQLite3|null データベース接続オブジェクト */
22    private ?SQLite3 $db = null;
23
24    /** @var string 暗号化に使用するキー */
25    private string $encryptionKey;
26
27    /** @var string 暗号化に使用する初期化ベクトル(IV) */
28    private string $iv;
29
30    /**
31     * コンストラクタ
32     *
33     * @param string $masterPassword マスターパスワードから暗号化キーとIVを生成
34     */
35    public function __construct(string $masterPassword)
36    {
37        // パスワードから固定長の暗号化キーを生成
38        $this->encryptionKey = hash('sha256', $masterPassword);
39        // パスワードとソルトから固定長のIVを生成 (IVは16バイトである必要があります)
40        $this->iv = substr(hash('sha256', 'iv_salt' . $masterPassword), 0, 16);
41    }
42
43    /**
44     * デストラクタ
45     * スクリプト終了時にデータベース接続を閉じ、ファイルをクリーンアップする
46     */
47    public function __destruct()
48    {
49        if ($this->db) {
50            $this->db->close();
51        }
52        if (file_exists(self::DB_FILENAME)) {
53            unlink(self::DB_FILENAME);
54        }
55    }
56
57    /**
58     * データベースを開き、テーブルを初期化する
59     *
60     * @return bool 処理の成否
61     */
62    public function initialize(): bool
63    {
64        try {
65            // SQLite3::open を使用してデータベースファイルを開く。
66            // フラグを指定し、読み書き可能かつファイルが存在しない場合は新規作成する。
67            $this->db = new SQLite3(self::DB_FILENAME, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE);
68
69            $createQuery = 'CREATE TABLE IF NOT EXISTS secrets (
70                key_name TEXT PRIMARY KEY,
71                encrypted_value TEXT NOT NULL
72            )';
73
74            return $this->db->exec($createQuery);
75        } catch (Exception) {
76            return false;
77        }
78    }
79
80    /**
81     * データを暗号化してデータベースに保存する
82     *
83     * @param string $key   データの識別キー
84     * @param string $value 保存する平文データ
85     * @return bool 処理の成否
86     */
87    public function saveData(string $key, string $value): bool
88    {
89        if ($this->db === null) {
90            return false;
91        }
92
93        // openssl_encrypt を使用して平文データを暗号化する
94        $encrypted = openssl_encrypt($value, self::ENCRYPTION_METHOD, $this->encryptionKey, 0, $this->iv);
95        if ($encrypted === false) {
96            return false;
97        }
98
99        $stmt = $this->db->prepare('INSERT OR REPLACE INTO secrets (key_name, encrypted_value) VALUES (:key, :value)');
100        $stmt->bindValue(':key', $key, SQLITE3_TEXT);
101        $stmt->bindValue(':value', $encrypted, SQLITE3_TEXT);
102        
103        return $stmt->execute() !== false;
104    }
105
106    /**
107     * データベースから暗号化データを読み込み、復号する
108     *
109     * @param string $key 読み込むデータの識別キー
110     * @return string|null 復号されたデータ。失敗時はnull
111     */
112    public function loadData(string $key): ?string
113    {
114        if ($this->db === null) {
115            return null;
116        }
117
118        $stmt = $this->db->prepare('SELECT encrypted_value FROM secrets WHERE key_name = :key');
119        $stmt->bindValue(':key', $key, SQLITE3_TEXT);
120        $result = $stmt->execute();
121        
122        $row = $result->fetchArray(SQLITE3_ASSOC);
123        if ($row === false) {
124            return null;
125        }
126        
127        $encryptedValue = $row['encrypted_value'];
128
129        // openssl_decrypt を使用して暗号化データを復号する
130        $decrypted = openssl_decrypt($encryptedValue, self::ENCRYPTION_METHOD, $this->encryptionKey, 0, $this->iv);
131
132        return $decrypted !== false ? $decrypted : null;
133    }
134}
135
136
137// --- 実行例 ---
138
139// アプリケーションの秘密のパスワード (実際には設定ファイルや環境変数から読み込む)
140$masterPassword = 'your-super-secret-password-12345';
141$handler = new EncryptedDatabaseHandler($masterPassword);
142
143if ($handler->initialize()) {
144    echo "データベースの初期化に成功しました。\n";
145
146    $secretMessage = 'これは秘密の情報です。';
147    $storageKey = 'api_key';
148
149    // 秘密のメッセージを暗号化して保存
150    if ($handler->saveData($storageKey, $secretMessage)) {
151        echo "データの保存に成功しました。\n";
152
153        // 保存したデータを読み込んで復号
154        $loadedMessage = $handler->loadData($storageKey);
155
156        if ($loadedMessage !== null) {
157            echo "読み込んだデータ: '{$loadedMessage}'\n";
158            assert($secretMessage === $loadedMessage, '復号したデータが元のデータと一致しません。');
159            echo "データの検証に成功しました。\n";
160        } else {
161            echo "データの読み込みまたは復号に失敗しました。\n";
162        }
163    } else {
164        echo "データの保存に失敗しました。\n";
165    }
166} else {
167    echo "データベースの初期化に失敗しました。\n";
168}
169// このスクリプトの終了時、__destructが呼ばれデータベースファイルが削除されます

このPHPコードは、SQLite3データベースにデータを安全に保存するため、openssl_encrypt関数を使って内容を暗号化する方法を示したサンプルです。

まず、initializeメソッドの中でnew SQLite3()を呼び出し、データベースファイルを開いています。これがリファレンス情報のopenメソッドの役割を果たします。第1引数の$filenameには、データベースとなるファイル名を指定します。第2引数の$flagsには、ファイルの開き方を指定する定数を設定します。このコードではSQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATEを指定しており、「読み書き可能」かつ「ファイルが存在しない場合は新規作成する」という動作になります。SQLite3::openの第3引数$encryptionKeyは、PHPに標準でバンドルされているSQLite3ライブラリではサポートされていないため、このサンプルでは使用していません。

代わりに、saveDataメソッドでopenssl_encrypt関数を使い、保存するデータを暗号化してからデータベースに格納します。そして、loadDataメソッドでデータを取り出す際には、対になるopenssl_decrypt関数で元のデータに復号します。この一連の処理により、データベースファイル自体ではなく、その中に保存する情報が暗号化され、安全性が高められています。open処理が成功すると、データベース操作が可能になり、失敗した場合は例外が発生します。

このコードは、データベースファイル自体ではなく、格納するデータを暗号化する方法を示しています。標準のPHPのSQLite3機能ではファイル暗号化がサポートされていないためです。注意点として、暗号化に用いる初期化ベクトル(IV)は、サンプルでは固定値ですが、実際の運用ではセキュリティ向上のため、暗号化ごとにランダムな値を生成し、暗号文と共に保存するのがより安全です。また、マスターパスワードをコード内に直接記述せず、環境変数など安全な方法で管理してください。最後に、スクリプト終了時にデータベースファイルを削除する処理はサンプル用のため、実際の開発ではデータを保持するために削除します。

関連コンテンツ

関連プログラミング言語