あっかぎのページ

WordPressでSQLite3を使ってハマったこと

20150611_1

WordPressでコンテンツデータにデータベース(SQLite3)を使ったときにハマったのでメモ。

コロリポプラン

コロリポプランでWordPressの記事に書きましたが、ただ今コロリポプラン(100円/月)でこのWebを作っています。



コロリポプランの制約でMySQLが使えませんが、SQLite3を利用することでWordPressも使えます(やり方の記事)。

SIM情報のWeb作成にデータベース使いたい → ハマる

SIM情報をまとめるために別のWebページを作っています。(SIMのページを検討中) このWebサイトも軌道に乗るまでは、今のコロリポプランにWordPressをインストールして、そこにそのまま作る予定です。

データベースを使いたい理由は「MVNOのプランとかがたくさんあるし変更も多いのでデータをひとまとめで管理したいな」と理由からです。コロリポプランではMySQLが使えないので、データベースにSQLite3を使う必要があるのですが、ここでハマりました。

ハマったのはSQLite3のデータベースを開く処理です。

    // $dbname = 'sqlite:' . get_bloginfo( 'template_url' ) . '/data/foo.db';
    $dbname = 'sqlite:' . '/var/www/foo/wp-content/themes/foo' . '/data/foo.db';

    $db = new PDO( $dbname );

素のApache上からはきちんとデータベースを開くことができるのに、WordPressを経由すると例外エラーが発生してデータベースが開けません。最終的にわかったことは、データベースのファイル名指定で

  • 1行目のWordPressの記述はNG (URL表記もNG)
  • 2行目の絶対パス の記述はOK

ということです。どうやらSQLite3でデータベースを読み込むときには絶対パスで指定が必要みたいです。PHP関数のfile_get_contentsで同じファイルを開くとWordPressの記述(とURL表記)でも普通に開けるので、SQLite3関連の仕様かもしれません。

これに気が付くまで、ファイルの所有権やApache・WordPressの設定などいろいろ右往左往してすごく時間がかかってしまいました。今後の備忘録も兼ねてメモとして残しておきます。

WordPressのコンテンツにデータベース(SQLite3)を使う

メモついでに、WordPressのコンテンツにデータベース(SQLite3)を使う方法も残しておきます。※WordPress本体にSQLiteを使う話ではありません。それについてはこちら→コロリポプランでWordPress

先ほどのSIM情報のWebコンテンツ用にデータベースを使う予定です。ページ内にMVNO情報を記載するのに、WordPressのショートコードとデータベースを組み合わせて簡単な記述で読み込めるようにします。

ショートコード

[foo id=2]

例えば、何かの固定ページや投稿ページ(page-foo.phpやsingle-foo.php)などで次のように記述。ここでは簡単のために1つのファイルにしていますが、前半のPHPはfunctions.phpに、後半のHTML部はpage.phpなどに分解するとわかりやすいと思います。

<?php
function get_db( $id ){
    // 絶対パスで指定しないとダメ
    // $dbname = 'sqlite:' . get_bloginfo( 'template_url' ) . '/data/foo.db';
    $dbname = 'sqlite:' . '/var/www/foo/wp-content/themes/foo' . '/data/foo.db';

    $db = new PDO( $dbname );

    // id=$idのデータ取得&表示
    $stmt = $db->prepare( 'SELECT * FROM foo where id=?' );
    $stmt->bindValue( 1, $id, PDO::PARAM_INT );
    $stmt->execute();
    $results = $stmt->fetchAll();
    foreach( $results as $row ){
        echo '<p>' . $row['id'] . ':' . $row['name'] . '</p>';
    }
    $db = null;
}

function foo_func( $atts ){
    extract( shortcode_atts( array(
        'id' => 999,
        'name' => 'xxx'
    ), $atts ) );
    get_db( $id );
}
add_shortcode( 'foo', 'foo_func' );

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title><?php the_title(); ?></title>
</head>
<body>
<?php
if( have_posts() ):
    while( have_posts() ) : the_post();
?>
    <?php the_content(); ?>
<?php
    endwhile;
endif;
?>
</body>
</html>

データベースの内容(foo.sql)

CREATE TABLE foo(id INTEGER, name TEXT);
INSERT INTO foo(id, name) VALUES(1, 'foo');
INSERT INTO foo(id, name) VALUES(2, 'bar');
INSERT INTO foo(id, name) VALUES(3, 'baz');

これを組み合わせると、ショートコード[foo]にid=?を指定すると関連するデータを取り出せます。ショートコードに変数を渡せることを知ったので、それをデータベースのSQL文と組み合わせるとすごく便利ですね。※データベース部はエラー処理が必要ですし、返り値を文字列にしたりHTMLを装飾するなどが必要になると思います。

WordPressのショートコードについてはこちらのページを参考にさせていただきました。

おわりに

本来WordPressでは、$wpdbを使ってMySQL上に新しいデータベースを作って操作するのがいいみたいです。WordPressを使っていて今回のようなSQLiteを使う場面は少ないかもしれませんが、PHPとSQLiteを組み合わせる場面にも使えるので、自分用のメモとしても残しておきます。