【php/pdoクラス】SQLite/phpLiteAdminでデータベース作成&アクセス制限・PDOクラスで記事データ取得してみる

2990文字

今回は、最近管理人が取り組んでいる『PHP/SQLiteでCMS作ってみるシリーズ』の続きです。実際にCMSを想定したテーブルを作って、PDOクラスで記事データを取ってみました。また、SQLiteの問題点ともいえるセキュリティ面の対策として、アクセス制限もつけてみます。早速内容を確認していきましょう。 (*前回の記事はこちら)

下準備~phpLiteAdminでCMSを想定したテーブル作成&データ格納

まず、記事を取る前に、CMSを想定したテーブル作成&データ格納を行います。新しく『c_posts』という名前でテーブルを作成。idはプライマリ&オートインクリメントにします。作ったフィールドは以下の通りです。

c_posts_id 投稿id
c_posts_date 投稿時間
形式『2023-06-03 20:00』
c_posts_modified 更新時間
更新時に保存
c_posts_description 概要欄
meta_description出力
c_posts_permanent_link パーマリンク
ドメイン後ろ部分
c_posts_status 公開(published)
または非公開(private)
c_posts_title 記事タイトル
c_posts_cat カテゴリ
セパレータで複数
c_posts_thumb アイキャッチ画像パス
c_posts_content 記事本文

そして、記事4つぶんくらい、こういう感じで作って、データベースに格納していきます。

データベース格納完了。なんか本格的っすね(笑)

SQLiteデータベースの問題点~直接ファイルにアクセスされるので、アクセス制限必須

SQLiteデータベースの問題点というと、これです。 パスワードとかもないので、無対策だと、場所がバレると直接アクセス&ダウンロードされます。『表示ディレクトリの外に置け』とは、こういう理由です。サーバーによっては『表示ディレクトリ以外の階層もある』んですけど(hetemlでいうとwebフォルダの外)、非公開ディレクトリが無い場合もあります。

そういう場合は.htaccessでアクセス制限をかけます。 全部denyにしてしまうとphpLiteAdminからもデータベースにアクセスできなくなるので、『設置ドメインのリファラは許可』という設定にしました。

で、作った.htaccessを、データベースファイルが入っているフォルダに入れます。

.htaccessアクセス制限のおかげで、万が一データベースファイルのurlがバレても、直接アクセスしてダウンロードできなくなりました。

phpLiteAdminで作成した、SQLiteデータベースから情報を取得してみる

記事後半では、上で作ったデータベースから、実際にデータを取ってみます。CMSで一般的に使われる形を想定して行ってみますか。

まずはデータベース接続テストで、var_dumpしてみる

前回同様、PDOクラスを使って記事を取ってみます。mysqlとことなり、SQLite接続時には、データベースユーザーやパスワードを必要としません(だからアクセス制限が必要というのもある)。とりあえず、c_postsテーブルから全件とるようなクエリを入れました。まずはテストでvar_dump。

データベース接続はokですね。[0]とか[1]みたいに配列の要素番号でも取れるけど、『[”c_posts_id”]=> int(4) [0]=> int(4)』みたいに返ってきているので、わかりやすいですね。

SQLiteデータベースに接続して、id指定し記事データを取るコードと表示例

コードはこんな感じになりました。『id指定』ということなので、『sqlのWHERE句でid指定(WHERE c_posts_id = 1)』というところがポイントです。これでidが1番の記事データが取得できます。 また、カテゴリは一つのフィールドにセパレータで区切って複数いれているので、まずexplodeで分割したあと、ループ回して全部出します。

表示例はこんな感じです。『CMSの個別記事ページ』みたいな表示になりました。

カテゴリで絞り込む場合はどうするか?

記事一覧やid指定はokですが、『CMSのとあるカテゴリのアーカイブ』みたいなときは、どうするでしょうか。今回管理人が設計したデータベースの構造上(カテゴリは一つのフィールドにセパレータで区切って複数)、『=で一致するもの』というのは使えなそうです。逆にカテゴリは1種類固定みたいなときは『=』で大丈夫なんですけど

そういう時は『like検索』を使ってみますか。文字列のどこかに『cat-a』が入っていればよいので、部分一致で『like “%cat-a%”』と書きます。 (前方一致のときは後ろに%、後方一致のときは前に%をつけます)

select * from c_posts WHERE c_posts_cat like “%cat-a%”

var_dumpしてみました。2記事がヒットしていることを確認。一方は『cat-a|cat-b』のセパレータ込み、もう一方は『cat-a』という値を持っています。あとはループ回して『タイトル・日付・アイキャッチ・概要』などを出力していけばokです。

なお、『like検索を複数のフィールドにかけるとめっちゃ重くなる』という懸念事項があります。今回はフィールドが1つ&記事データ数が一桁だけだったので、そこまで遅いという印象はなかったです。phpLiteAdmin上でSQLを実行してみたところ『2 行表示(クエリは 0.0003 秒かかりました)』という表示がでました。

あとがき・まとめ

  • SQLiteデータベースは直接アクセスされるとまずいので、公開領域の外に置くか、アクセス制限をかける
  • PDOでSQLite接続時には、データベースユーザーやパスワードを必要としない
  • id指定時のクエリは『WHERE 〇〇(idのフィールド) = ◇◇(idの数値)』という形に
  • 特定の文字列でヒットさせたいときはlike検索

まとめると、こんなところでしょうか。SQLiteは初めて使いましたが、mysqlやWordPressのwpdbクラスで使うようなSQLがそのまま使えたので、そこまで苦戦しませんでした。フロントはなんとかなりそうなので、あとは管理画面でINSERT・UPDATE・DELETEみたいな機能もやってみる予定です。

WordPressサイト制作&リニューアル・機能開発サービス | アトリエSS


【カテゴリ】- PHP・データベースetc
【タグ】- , , ,

関連記事

【PHPファイル取得でmidiデータ配布サイト】glob関数とWordPress関数で、midiダウンロード&関連記事一覧を作成
YouTube Data APIを使って、PHPで『タイトル・動画id・サムネイル画像』などを取得してみる(Search: listリソース)
【PHP etc.プログラム学習サイトコードコピペ】全角引用符・バッククオートが入ってて動かない件に注意
【PHP】GD関数『imagewebp』でのWebP変換方法&使えないポイント
【WordPressカスタムフィールド検索】meta_queryで、シリアライズ値が入ったフィールドを持つ記事をヒットさせるには?
WPデータベースの余計なデータには何がある?事例と対処方法・あるとイヤなケース
PHP・shuffleやarrayを使った、画像ランダム表示方法~メインビジュアルやバナー・テキストにも利用可能
侍エンジニア塾ブログにあったPHPコードをシンプルに書いてみる(foreachで配列キーや値取得・continueで空要素スキップ)
【WordPressでPHPプログラムを学習シリーズ1】用語:PHP変数・関数・定数を、WPの機能を通して覚える
【PHPプログラミング】PDOクラスを使って、WPのget_post_metaで取れないプラグイン独自テーブルを取得する
【PHP学習】var_dumpで出力するのと、echoで出力するのは、挙動がどのように違うの?
WordPress記事一覧ページの『本文からの抜粋』を表示する関数と、その文字数の調整方法をチェックする