PHPによるSQLite

ここではSQLiteのバージョン2 (SQLite2) を使用することを前提として解説します。

PHP 5.4以降、標準で同梱されているのはSQLite3です。

PHPのSQLiteに関する関数 (一部)
分類 関数 説明
接続 sqlite_open データベースへ接続
(データベースファイルを開く)
sqlite_close データベースへの接続を解除
(データベースファイルを閉じる)
取得 sqlite_current 結果セットから、カレントレコードを取得
(処理後に次のレコードへ移動しない)
sqlite_fetch_array 結果セットから、カレントレコードを取得
(処理後に次のレコードへ移動する)
sqlite_fetch_single
sqlite_fetch_string
結果セットから、カレントレコードの最初のフィールドを取得
sqlite_array_query SQLコマンドを実行し、結果を配列で取得
sqlite_num_rows 結果セットから、レコード件数を取得
シーク sqlite_seek 特定のレコードへシーク
sqlite_rewind 先頭のレコードへシーク
sqlite_next 次のレコードへシーク
クエリ実行 sqlite_exec SQLコマンドの実行 (複数のクエリも可能)
sqlite_query SQLコマンドを実行し結果を受け取る
sqlite_unbuffered_query SQLコマンドを実行し結果を受け取る
(結果セットへの高速アクセス。ランダムアクセス不可)
エスケープ sqlite_escape_string SQLiteのSQL文用に、文字列をエスケープ
PHP: SQLite 関数 - Manual

これらはSQLite2の関数です。SQLite3には別のモジュールが用意されています。

SQLiteコマンド

exec()関数を使用することで、SQLiteコマンドを実行できます。そのためには、SQLiteのコマンドラインプログラムを、起動パラメータにコマンドを与えて実行します。

echo exec( 'sqlite.exe sample.db .schema' );
PHP: exec - Manual

SQLite関数

SQLite関数sqlite_query()で実行し、sqlite_fetch_single()で結果を取得できます。
※このSQLite関数はSQLiteの関数であって、PHPのSQLiteに関する関数とは異なるものです。

$result = sqlite_query( $dbhandle, 'SELECT count( * ) FROM table1' );
$count = intval( sqlite_fetch_single( $result ) );

データベースへの接続

接続 (ファイルを開く)

resource sqlite_open(
    string $filename           // データベースのファイル名
    [, int $mode = 0666        // モード
    [, string &$error_message  // エラー発生時のエラーメッセージ格納用
    ] ] )

接続解除 (ファイルを閉じる)

void sqlite_close(
    resource $dbhandle    // データベースハンドル
    )

テーブルの作成

テーブルの作成にはCREATEコマンドを使用します。

$query = "CREATE TABLE user(id, name)";
sqlite_query( $dbhandle, $query );

テーブルの存在確認

sqlite_masterテーブルに、指定のテーブルが存在するか問い合わせます。

$query = "SELECT count(*) FROM sqlite_master WHERE type='table' AND name='{$tableName}'";
$handle = sqlite_query( $dbhandle, $query );

if( sqlite_fetch_single( $handle ) == 1 )
{
    // テーブルあり
}

データの追加

データの追加にはINSERTコマンドを使用します。

// データベースを開く (存在しないならば作成する)
$dbhandle = sqlite_open( DATABASE_NAME );

if( $dbhandle )
{
    $query = "INSERT INTO $tableName( field1, field2 )"
        ." VALUES( 256, 'abc' )";

    // データベースにSQLステートメントを実行する
    sqlite_query( $dbhandle, $query );

    // データベースを閉じる
    sqlite_close( $dbhandle );
}

文字列のエスケープ

フィールド値に文字列を追加するときには、SQL文が正しく解釈されるために、それをエスケープする必要がある場合があります。

sqlite_escape_string()関数はシングルクォート ( ' ) を、2つ並べた形式 ( '' ) に置換します。これはSQLインジェクションにも効果的です。

string sqlite_escape_string( string $item )

トランザクション

SQLiteでは更新コマンドごとに自動的にトランザクションが開始されるため、通常は明示的に実行する必要はありません。しかしそのために、多量のデータを追加するときには処理が遅くなる問題があります。よってそのような場合には明示的にトランザクションを宣言すべきです。

// データベースを開く (存在しないならば作成する)
$dbhandle = sqlite_open( DATABASE_NAME, 0666, $databaseOpenError );
if( $dbhandle )
{
    // トランザクションを開始する
    if( sqlite_query( $dbhandle, 'BEGIN' ) )
    {
        $query = "INSERT INTO $tableName( field1 ) VALUES( 'abc' )";

        // データベースにSQLステートメントを実行する
        if( sqlite_query( $dbhandle, $query, SQLITE_BOTH, $databaseWriteError ) )
        {
            // トランザクションをコミットする
            sqlite_query( $dbhandle, 'COMMIT' );
        }
        else
        {
            // トランザクションをロールバックする
            sqlite_query( $dbhandle, 'ROLLBACK' );
        }
    }

    // データベースを閉じる
    sqlite_close( $dbhandle );
}

データの取得

データの取得にはSELECTコマンドを使用します。

ここでは次のテーブルからデータを取得することを考えます。

table1
  field1 field2
1 10 a
2 20 b

結果セットから、レコードごとに最初の値だけを取得

sqlite_fetch_single()関数で、結果レコードの最初の値を取得できます。

string sqlite_fetch_single (
    resource $result
    [, bool $decode_binary = TRUE ] )
PHP: sqlite_fetch_single - Manual
$dbhandle = sqlite_open( DATABASE_NAME );

$query = 'SELECT * FROM table1'
$handle = sqlite_query( $dbhandle, $query );

echo sqlite_fetch_single( $handle );

これは上記のテーブル (table1) に対して、

10

のような出力をします。

結果セットから、レコードごとに取得

SELECTコマンドで取得したデータは、sqlite_fetch_array()関数でレコードごとに配列として取得できます。なおその引数にSQLITE_ASSOCと指定すると連想配列のキーが、SQLITE_NUMとするとインデックスが結果として返されます。PHP: sqlite_fetch_array - Manual

結果配列の添の定義
定数 意味
SQLITE_ASSOC 連想配列 (Associative array) の添字 (名前フィールド) のみ
SQLITE_NUM 数値の添字 (フィールド番号) のみ
SQLITE_BOTH 連想配列の添字と数値の添字の両方 (既定)

この例のようにデータベースの前方から順にアクセスするだけならば、SELECTコマンドの実行はsqlite_query()ではなく、sqlite_unbuffered_query()の方が高速に処理できます。

$dbhandle = sqlite_open( DATABASE_NAME );

$query = 'SELECT * FROM table1';
$handle = sqlite_query( $dbhandle, $query );

// 結果ハンドルから、レコードを配列として取得する
while( $record = sqlite_fetch_array( $handle, SQLITE_ASSOC ) )
{
    print_r( $record );
}

出力例

Array
(
    [field1] => 10
    [field2] => a
)
Array
(
    [field1] => 20
    [field2] => b
)

結果セットから、すべてを取得

sqlite_array_query()関数を使用すると、SELECTコマンドの結果のすべてを配列として取得できます。(この関数は、結果レコードが45件以下のクエリーに対してのみ使用すべきです) PHP: sqlite_array_query - Manual

$dbhandle = sqlite_open( DATABASE_NAME );

$query = 'SELECT * FROM table1';
$result = sqlite_array_query( $dbhandle, $query, SQLITE_ASSOC );

print_r( $result );

出力例

Array
(
    [0] => Array
        (
            [field1] => 10
            [field2] => a
        )

    [1] => Array
        (
            [field1] => 20
            [field2] => b
        )
)

データ件数の取得

sqlite_num_rows()で、指定条件に一致するデータの件数を取得できます。

次の例では、table1テーブルのfield1の値が10以上のデータの件数を取得しています。

$query = 'SELECT * FROM table1 WHERE field1 >= 10';
$handle = sqlite_query( $dbhandle, $query );

$count = sqlite_num_rows( $handle );
※クエリを実行するのにsqlite_unbuffered_query()を使用するとsqlite_num_rows()は実行できないため、sqlite_query()を使用する必要があります。

SQLite関数を使用する方法

SQLite関数countを使用する方法でも、データの件数を調べられます。

コマンドはsqlite_query()で実行し、結果の値は1つ受け取るだけでよいのでsqlite_fetch_single()で取得します。

$query = 'SELECT count( * ) FROM table1 WHERE field1 >= 10';
$handle = sqlite_query( $dbhandle, $query );

$count = sqlite_fetch_single( $handle );

高度な検索

キーワードが含まれているレコードを取得するだけならば、LIKE条件とワイルドカードを使用して、

WHERE field1 LIKE '%keyword%'

とします。ここではそれ以外の、より複雑な条件でのレコードの取得方法について解説します。

正規表現

まず正規表現を処理する関数を作成します。そしてsqlite_create_function()で、そのユーザー定義関数をUDF (User Defined Functions) として登録します。

// 正規表現を処理する関数
function regex_callback( $pattern, $subject )
{
    return preg_match( $pattern, $subject );
}

// regex_callback()が、SQL文においてregex()でコールされるように登録する
sqlite_create_function( $dbhandle, 'regex', 'regex_callback', 2 );

$query = "SELECT * FROM table1 WHERE regex( '/[0-9]+/', field1 )";
$handle = sqlite_query( $dbhandle, $query );
void sqlite_create_function (
    resource $dbhandle ,
    string $function_name , // SQL文で使用する関数名
    callable $callback      // SQLを処理するコールバック関数
    [, int $num_args = -1 ] // コールバック関数の引数の数
    )
PHP: sqlite_create_function - Manual

SQLファイルの実行

複雑なSQLは外部のファイルに記述した方が管理が容易になります。テキストエディタでSQLを記述し、拡張子を.sqlとして保存します。(ここの内容では拡張子は無関係ですが…)

SQLファイルはfile_get_contents()でテキストとして読み込めますので、それをsqlite_exec()により実行します。

// データベースを作成する
$dbhandle = sqlite_open( DATABASE_NAME );

// SQLファイルからクエリを読み込む
$query = file_get_contents( SQL_FILENAME );

// クエリを実行する
sqlite_exec( $dbhandle, $query );

SQLiteの文字エンコーディング

クエリの文字エンコーディングがSQLiteのそれと一致していない場合、クエリの実行に失敗します。そのときのエラーは、

Warning: sqlite_exec() [function.sqlite-exec]:
  near "CREATE": syntax error in C:\index.php on line 256

のようなものです。

SQLiteの文字エンコーディングは、既定ではiso8859となっています。これはphp.iniのSQLite Encodingの項目で確認できます。またはsqlite_libencoding()関数でも可能です。PHP: sqlite_libencoding - Manual

PHPのマニュアルから検索