|||||||||||||||||||||

なんぶ電子

- 更新: 

PHPでSQLite3

PHP sqlite3

PHPに標準で有効になっているSQLite拡張モジュールを利用します。サンプルとして利用した環境はDebian11ですが、Windows11環境にも触れながら進めていきます。

初期設定

Debian11においてはAPTで「php7.4-sqlite3」モジュールのインストール、Windows11の場合はphp.iniでSqlite3拡張を有効化する必要があります。

またPHPはバージョンを8を想定環境にしています。バージョンにより挙動が違うことがあります。

php.ini(Windows)

...
;extension=pdo_pgsql
# コメントアウトを解除します。
extension=pdo_sqlite
;extension=pgsql
...

詳しくはSQLiteの公式ドキュメントを確認してもらえればと思いますが、SQLiteにおいての列のタイプは次のようになります。

  • INTEGER

    符号付の最大8バイトの整数値です。サイズは値によって自動で変わります。

  • REAL

    8バイトの浮動小数点数です。

  • TEXT

    テキストです。対応するエンコーディングはUTF-8、UTF-16BE、UTF-16LEとなります。

  • BLOB

    バイナリデータを保持します。

  • NULL

SQLite3インスタンスの生成とデータベースオープン

SQLite3はオブジェクト志向型のライブラリとなっています。次のようにしてインスタンスを生成します。

インスタンスからopenメソッドを使うことで、SQLite3データベースをオープンします。

# インスタンスの生成とデータベースオープン
$sqlite3 = new SQLite3('./sqlite3.db',SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE,"");

openメソッドの第1引数にはデータベースファイルへのパスを渡します。第2引数、第3引数はオプションで、フラグ、暗号化キーとなります。

フラグには次の種類があります。

  • SQLITE3_OPEN_READWRITE

    データベースファイルを読み書き用でオープンします

  • SQLITE3_OPEN_READONLY

    データベースを読み込み専用でオープンします

  • SQLITE3_OPEN_CREATE

    第1引数で指定したファイルが存在しない場合は生成します

デフォルトでは「SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE」(読み書き・未存在時生成)となっています。

第3引数の暗号化キーは文字列で渡します。通常暗号化モジュールが存在しない為パラメータは無視されます。

openメソッドと同じパラメータをコンストラクタに渡すことで、オープン済みのSQLite3データベースのインスタンスを取得することもできます。

SQLite3インスタンスのメソッド

SQLの実行はSQLite3のインスタンスから実行します。たとえば結果(表)を返さないSQLを実行するにはexecメソッドを使います。

$sqlite3->exec('CREATE TABLE sample (column1 TEXT)');

SQLite3クラスが持つそのほかの主なメソッドは次の通りです。

  • prepare($query)

    プリペアドステートメントを準備します。後で紹介するステートメントオブジェクトが変えるので、以降はそちらから操作します。

    プレースホルダは「:」または「@」の後に任意の名前を付けます。公式ページには掲載されていませんでしたが、?の記法を使うこともできるようです。

    $ps = $sqlite3->prepare("INSERT INTO users_table VALUES(:id,:name)");
    $ps->bindValue(':no',0,SQLITE3_INTEGER);
    $ps->bindValue(':name','User Name',SQLITE3_TEXT);
    
    $ps = $sqlite3->prepare("INSERT INTO users_table VALUES(@id,@name)");
    $ps->bindValue('@no',0,SQLITE3_INTEGER);
    $ps->bindValue('@name','User Name',SQLITE3_TEXT);
    
    $ps = $sqlite3->prepare("INSERT INTO users_table VALUES(?,?)");
    $ps->bindValue(1,0,SQLITE3_INTEGER);
    $ps->bindValue(2,'User Name',SQLITE3_TEXT);
    

    数値での指定は、?を使った場合だけでなく:や@を使うときでも可能です。この時数値は1から始まります。

  • query($query)

    値(表)を返すSQLを実行します。戻り値は後で紹介するリザルトクラスで返ります。以降はそちから操作をします。

  • close()

    データベース接続を切断します。

リザルト

SQLiteインスタンスや、ステートメントからはSQLite3Resultクラスで結果が返ります。

ここからFetchArrayを実行することで行や列の値を取得することができます。

$res = $sqlite3->query("SELECT * FROM users_table");

$arr = $res->fetchArray();

// 行が無い場合はfalseが返ります
if ($arr !== false) {
  // カラム名か、0から始まるインデックスで列を取得します
  echo $arr[0];
}

// 結果を閉じます
$res->finalize();

各メソッドの詳細は次のようになっています。

  • columnName($列番号)

    0から始まる列番号を指定して列名を取得します。ASで別名を付けた場合はその名前が戻ります。

  • columnType($列番号)

    0から始まる列番号を指定して列のタイプが返ります。成功時の戻り値はSQLITE3_INTEGER、SQLITE3_FLOAT、 SQLITE3_TEXT、SQLITE3_BLOB、SQLITE3_NULL のいずれか、失敗時はFalseになります。

  • fetchArray($mode)

    結果の行を取得します。modeにSQLITE3_ASSOCを指定すると連想配列、SQLITE3_NUMを指定すると数値添字配列で返ります。SQLITE3_BOTHを指定するとその両方を取得します。

    行が無い場合はfalseを返します。

  • numColumns()

    結果の行のカラム数を取得します。カラム数をfetchArrayで得られる配列からcountで取得しようとすると、SQLITE3_BOTHを指定時には倍になってしまうのでこのメソッドを利用する方が確実です。

  • finalize()

    結果セットを閉じます。戻り値は常にTrueです。

  • reset()

    結果セットを先頭行に戻します。

ステートメント

ステートメントはSQLite3オブジェクトのprepareメソッドの戻り値として受け取ることが多いオブジェクトです。

# ステートメントオブジェクトの生成
$stmt = $sqlite3->prepare("SELECT * FROM users_table WHERE id=:id");
# 値のバインド
$stmt->bindValue(':id',10,SQLITE3_INTEGER);
# 実行すると先のリザルトが返ります。クエリが値(表)を返さない場合も同様です。
$res = $stmt->execute();

if($res != false) {
  while($arr = $res->fetchArray()) {
    echo $arr['id'].$arr['name'];
  }
  $res->finalize();
}

ステートメントが持つメソッドは次の通りです。

  • bindParam($バインド位置, $値, $type);

    文字列または1からはじまる数値で示されるバインド位置に、値をバインドします。

    typeにはセットする値に適合するタイプを、SQLITE3_INTEGER、SQLITE3_FLOAT、 SQLITE3_TEXT、SQLITE3_BLOB、SQLITE3_NULLのいずれかから選択します。ただし、値がNULLだった場合はSQLITE3_NULLとなります。

    省略した場合は値から自動判別されます。

  • bindValue($バインド位置, $値, $type);

    パラメーターに変数の値をバインドします。bindParamとの違いはbindParamが値を参照渡しするのに対し、bindVlueは値渡しとなります。

  • clear()

    バインドされているすべてのパラメータをクリアします。

  • reset()

    プリペアドステートメントを実行前の状態に戻しますが、バインドした内容はそのままです。

  • close()

    プリペアドステートメントを閉じます。

  • getSQL($expand)

    ステートメントのSQLを取得します。$expandにTrueを設定すると、バインドした箇所はその値、バインドされていない箇所はNULLがセットされた状態のSQLが返ります。$expandの値をFalseにすると、SQLite3インスタンスのprepareに渡したSQLがそのまま返ります。

  • execute()

    バインドした値でプリペアドステートメントを実行します。戻り値はリザルトクラスが返ります。同じステートメントクラスから複数回executeを呼んだ際、得られるリザルトは独立していないため1回ごとにリザルトをfinalize()することが推奨されています。

トランザクション

多くのDBMSがそうなようにSQLiteも暗黙のCommitをします。そのため大量のデータを取り扱う場合はトランザクションを発行すると処理が早いです。ただPHPのライブラリにはトランザクション専用のメソッドは用意されていないため、execメソッドで実行します。

  • begin transaction

    トランザクションを開始します。

    $sqlite3->exec("begin transaction");
  • rollback transaction

    ロールバックします。

    $sqlite3->exec("rollback transaction");
  • commit transaction

    コミットします。

    $sqlite3->exec("commit transaction");

筆者紹介


自分の写真
がーふぁ、とか、ふぃんてっく、とか世の中すっかりハイテクになってしまいました。プログラムのコーディングに触れることもある筆者ですが、自分の作業は硯と筆で文字をかいているみたいな古臭いものだと思っています。 今やこんな風にブログを書くことすらAIにとって代わられそうなほど技術は進んでいます。 生活やビジネスでPCを活用しようとするとき、そんな第一線の技術と比べてしまうとやる気が失せてしまいがちですが、おいしいお惣菜をネットで注文できる時代でも、手作りの味はすたれていません。 提示されたもの(アプリ)に自分を合わせるのでなく、自分の活動にあったアプリを作る。それがPC活用の基本なんじゃなかと思います。 そんな意見に同調していただける方向けにLinuxのDebianOSをはじめとした基本無料のアプリの使い方を紹介できたらなと考えています。

広告