2020/04/23 23:29
データベースの「独自テーブル追加」でメール受信履歴一覧を作成する方法
“せっかくPHPを使うなら”という事でDB(データベース)を自由にいじりたい!
そんな感じの記事です。「データベース操作」の解説記事となります。
ちなみに今回、Wordpressを使った場合の例とした解説・説明となりますのでご了承ください。
今回やりたかった事
・データベースにオリジナルの「箱」的なものを作る
・その“入れ物”に対して自由にテキストデータ等を動的に出し入れする
・しかもそれを管理画面じゃなくサイト上(ページ内)でいじれるようにする
イメージ的には独自にオリジナルのDBを自由に作成して、ページ内でそれを動的に表示・追加・変更・削除できるような管理をする、といった感じでしょうか。
こういうのに使えますっていう例がコチラです。
例)
サイト上でユーザーから申込フォームでメールが送られたとする
↓
もちろん管理者宛にメール届く
↓
管理者権限でログインすると
サイトのページ上でもそれらのメール内容が一覧で見れる
↓
現在の受付状況を表すような「ステータス」項目を作っておいて、最初は【申込】の状態から、動的にこちらの意思で【受理】や【キャンセル】等に変更ができるようにしたい
↓
現在の状況(ステータス的な)を一覧で見れるので管理もしやすくなる
今回は、ある案件のサイトで作ってみたものでそのフローを説明します。
イメージとしてはこういった形の一覧ですかね。下記は飲食店予約システムのイメージとなります。
①メールを受信したとする
まずは申込の為のメールをユーザーが送ったとします
つまり「リクエスト」されたとする
例えば、「予約」や「購入」や何かしらユーザーからのリクエストがあった場合と過程します。
管理者側では「リクエスト一覧」で申し込まれた内容が表示される。
※この時点で既にDBへと保存されていて、それを呼び出して表示させている状態
②リクエストを受理に変更する
「受付状況」がデフォは“申込中”となっていて、受理する場合はそれを“受理”に変更してボタンをポチる。
ポチった時点で受理への変更が完了となり、DBも書き換わる。
これらのDB書き換えや表示をクリック1つで全て可能にさせる為のDB操作の説明となります。
データベース独自テーブルの作成
そういった“オリジナルのデータベース”つまり「データベース独自テーブル」というものを作るところからスタートです。
あくまで初心者向けの解説となります。
さて、ここからが本題となります。
【必要となる事】
・phpMyAdminをいじる
・WPのDBファイルに一言追記
・PHPファイルへの記述
やることとしては以上となります。
※プラグイン不要
※MySQLに関しての知識も取り合えずは不要
ではちょっとずつ解説していきます。
【ちょっとした余談】
「CRUD」(クラッド)
RDBMS(MySQLのようなリレーショナルデータベース管理システム)には、CRUDという言葉があるらしく
作成 (Create)
取得 (Retrieve)
更新 (Update)
削除 (Delete)
上記の頭文字でCRUDですね。
そしてそれらに必要と言われている労力
CREATE 10%
RETRIEVE 80%
UPDATE 8%
DELETE 2%
つまり、作成して取得(表示)させるまでが大変で、そこまでクリアできたら後は簡単よって話。
プログラミングは「情報の取得」までが難しいと言われてまして、それが理解できれば残りの処理を覚えるのは余裕だぜって事らしいです。
それらを踏まえて話を進めていきましょう。
phpMyAdminのいじり方
ではやっとこさ実践へと進みます。
phpMyAdminを使う方法と、使わずにコードでDBを作成する方法があるようですが、phpMyAdminで直感的な操作をした方が分かりやすいと思うので、解説はそちらで進めます。
DBをいじるとか、最初はかなり取っつきにくいんですが、実際にやってみるとそんなに難しくありません。
①phpMyAdminへログイン
レンタルサーバー(ロリポップやさくらやエックスサーバー等)
↓
データベース
↓
操作する
↓
ログイン
つまり本番環境のデータベースの話です。
WordPressとか普段から使ってるような人はログインした事あると思いますが、初めての方は「レンタルサーバー データベース ログイン方法」とかでググってみてください。
②DB(phpMyAdmin)にログインしたら
左のサイドバーでいじるデータベースを選択
③テーブル一覧
メイン画面にテーブル一覧がずらっと表示される。
④テーブル作成
一番下にある「テーブルを作成」の箇所を使う。
⑤名前とカラム数を選択
名前はテーブルの名前
カラム数はフィールドの数
例)
メールでの申し込みに関してのリストなので、仮に名前をつけてみて説明していきます。
名前→wp_apply_list
※この時に「wp_」のプレフィックスも含める事
内容は例えば、「通し番号(ID)」「名前」「メアド」「内容」「受付状況(ステータス)」の5種類のフィールドが必要なので
カラム→5
みたいな。
※後でカラムの追加や削除もできます
⑥カラム設定
通し番号の名前は任意で「apply_id」とかにしてオートインクリメント(A_I)にチェックをつけておくというのが前提でいいかなと思います。
オートインクリメントってのは自動で連番の数字がつくやつです。
追加されると勝手にナンバリングされる設定って事です。
後は「名前」「メアド」「内容」「受付状況(ステータス)」それぞれに任意の名前(半角英数字)で設定しておきます。
取り合えず例として
apply_id
apply_name
apply_mail
apply_desc
apply_status
…という形に名前を設定したとします。
ここは半角英数字にしてください。
・「データ型」の指定について
データ型という項目はその入力されるものが文字列なのか数字の値なのかを指定するものだと思ってください。
例えばそこの枠には文字列が入る場所であれば「TEXT」型でいいかと。
IDのように数字しか入らないなら「INT」型とかでもいいと思います。
他にもDATEとかいろいろありますが、取り合ずはTEXTかINTで進めます。
⑦保存
設定ができたら「保存」して
上のタブメニューから「挿入」タブを選択するとテーブルへ実際にデータを入力する事ができます。 まずは表示テスト用に仮で適当に入れておくといいかもです。
ちなみに下記画像は実際に作成した案件のDB画面ですが、「表示」タブを見てみるとにこういう感じで1行ずつ追加されてるのが分かります↓
wp-db.phpを編集
では実際に今度はWPファイルをいじっていきます。
まずはWPフォルダを見てください。
普段あまりいじる事のないフォルダの場所ですが
ワードプレスフォルダ/wp-includes/wp-db.php
この「wp-db.php」ファイルを開きます。
↓250行目前後にこういうのがあるので
var $tables = array(
'posts',
'comments',
'links',
'options',
'postmeta',
'terms',
'term_taxonomy',
'term_relationships',
'termmeta',
'commentmeta',
'apply_list', //←ここに追記する
);
先ほど作ったDBの「テーブル名」を追記します。
この時は「wp_」とかのプレフィックスは不要です。
追記したら上書き保存して終了します。
【重要】
上記の方法では「WP自体の更新」があった時に上書きされてしまいます。
これは「wp-db.php」ファイル自体が更新によって上書きされ、書いた記述が消えてしまうという事です。
更新する度に毎回追加するのも面倒なので下記の方法で対策しましょう。
・wp-db.phpの上書きを回避する対策
①db.php新規ファイル作成
「wp-content」フォルダの直下に新しく「db.php」というファイルを作ってください。
②作成したファイル内へ記述
下記を記述。
<?php
require_once( ABSPATH . WPINC . '/wp-db.php' );
class my_wpdb extends wpdb {
// areaとprefという名前のデータベースを追加で読み込んでみます。
var $tables = array(
'posts',
'comments',
'links',
'options',
'postmeta',
'terms',
'term_taxonomy',
'term_relationships',
'termmeta',
'commentmeta',
'apply_list' //←先ほどの追加したものも記述
);
}
if ( ! isset($wpdb) ) {
$wpdb = new my_wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
}
③保存する
記述したらそのまま保存してください。
・説明
これは「wp-db.php」ファイル内の記述を別ファイルから上書きで読込させてるって事になります。
この新しく作った「db.php」ファイルはWPの更新に影響がないので、そのまま使用するテーブルの記述を上書きし続けてくれるというものになります。
wp-db.phpよりもcontent直下のdb.phpファイルがある場合は優先的に読み込む仕様になってるようです。
次にDBからの取得方法
ここまでで「CRUD」で言うところの「作成 (Create)」が出来たも同然です。
次に「取得 (Retrieve)」へと進みます。
【DB内容を表示させる】
まずサンプルの記述です。基本的なDBのテーブルの表示方法となります。
<?php
global $wpdb;
$query = "SELECT * FROM $wpdb->apply_list";
$results = $wpdb->get_results($query);
foreach($results as $row) {
echo "<p>ID:" . $row->apply_id . "名前:" . $row->apply_name . "メアド:" . $row->apply_mail . "内容:" . $row->apply_desc . "ステータス:" . $row->apply_status . "</p>";
}
?>
上記一式、これが表示の場合の基本セットだと思ってもらっていいです。
こうやって見るとけっこう短い記述で済みますね。
※実践で使う時は「管理者権限でログインしてる時だけ」表示させるようにするとベターだと思います
※PHPファイルのどこにでも表示可能です
これによって独自テーブルの中身(情報)が一覧で表示されます。
後はforeach内でechoしてる箇所にclassを当てて成型していく感じです。
グリッドとかで並べてもいいし、table、tr、tdで並べるのもアリですね。
【説明】
・お作法として1行目の最初「global $wpdb;」でグローバル(どこでも呼び出し可能)状態にします。
・「SELECT」っていうのは表示する場合に使います。更新や削除はまた少し変わります。
ちなみに「*」は“全て”という意味になります。
・「FROM」というのはDBテーブル名を指定するのに必要な記述です。
この指定がないと、どのテーブルを呼び出すのか不明になるので注意
・情報を取得してforeachで内容があるだけ全てをループさせます。
・ループ内でそれぞれのテーブル内のフィールドを表示させます。
もちろんテーブル内の項目の記述したものだけを吐き出せる訳なので
例えば、取得した5種類のカラムのうち表示させたいのは「apply_mail」1つだけでいいっていう場合にももちろん対応できます
以上が基本的な表示方法です。
【補足】
「SELECT」内で使える種類
FROM →データベーステーブル名の指定。記述必須。
ORDER BY →何基準で並べるか。何の順番で表示させるかって事ですね
ASC/DESC →昇順・降順
WHERE →縛りの条件(例えばapply_id = '申込中'のものだけを表示させる等)
LIMIT →数字を入れる事で表示させる数を制限する(「10」とすれば10件。「5,10」とすれば5件目から10件目まで)
…などが存在してます。
例えばこんな書き方ができます。
$query = "SELECT * FROM $wpdb->apply_list ORDER BY apply_id DESC LIMIT 100";
という形にすれば
DBテーブル「apply_list」の中身全て、表示させる順番は「apply_id」の「降順」で「100件」だけ取得する
…という指定になります。
【応用1】
DBテーブル内のカウント数を数える
そのテーブル内にいくつ保存された行数があるのか、というカウントです。
単純に中身に何個のデータがあるのかを表示させたい時に使います。
$table_count = $wpdb->get_var("SELECT count(*) FROM $wpdb->apply_list);
echo $table_count; //カウント数を表示
これでDB「apply_list」内のデータがいくつあるのかカウント表示させる事ができます。
【応用2】
あらかじめ計算によって「何件表示」させたいかと、「何ページ目」かを割り出してページネーションを作成する事もできる。
<?php
// 1ページ内の表示数を指定
$paged = 10;
// 現在のページ数を取得する(未入力の場合は1を挿入)
$url = $_SERVER['REQUEST_URI'];
// URL内の「●●/」が何文字目かを取得
$pos = strpos($url, "●●/");
// 取得した文字列の次の文字を100文字取得(ページ数)
$str = substr($url, $pos + 3, 100);
// 上記ちょっと難しい記述ですが
// 例えばページ名が「history」という名前のPHPファイルだったとすると
// $pos = strpos($url, "history/");
// とさせ、「history/」が8文字分となるので
// $str = substr($url, $pos + 8, 1);
// という形にする事で「history/2」という時に9文字目となる「2」の部分のページ数の取得ができます。
// URLに数字が含まれていればページネーション設定
if($str) {
$page = (int)$str;
// なければ1ページ目に設定
} else {
$page = 1;
}
// スタートのポジションを計算する
if ($page > 1) {
$start = ($page * $paged) - $paged;
} else {
$start = 0;
}
$query = "SELECT * FROM $wpdb->apply_list LIMIT {$start}, {$paged}";
?>
<?php
// テーブルのデータ件数を取得する
$table_count = $wpdb->get_var("SELECT count(*) FROM $wpdb->apply_list");
// ページネーションの数を取得する
$page_count = ceil($table_count / $paged);
?>
<?php
// ページネーションのボタン箇所
for ( $x = 1; $x <= $page_count ; $x++ ) :?>
<a href="<?php echo home_url('');?>/●●?page=<?php echo $x ?>"><?php echo $x; ?></a>
<?php endfor;?>
ちょっとややこしいかもですが、やっていくうちに何となく分かります。
DBへの新規追加方法
取り合えず表示方法はざっくりと分かったと思うので、次に基本となる「DBへの新規追加」の方法です。
INSERT(インサート)を使います。
SELECTの時とは書き方がちょっと変わります。
例えば今回のメール履歴一覧の表示を例にすると、追加されるタイミングは以下のようなイメージで作ってみます。
サイト内でユーザーから申込のメールが送信されるとする
↓
そのメールフォームの内容をそっくりそのままDBへ突っ込んでいく
(ココでDB内に新規追加させたい)
という流れを想定した記述方法です。
この場合は例えばですがメールフォームのaction先となる「mail.php」ファイル内などに書いとくと良いかと思います。
メール送信内容を処理するタイミングのファイル内という事です。
「メールが(POST)送信され、mail.phpファイル等を経由し、サンクスページへと遷移するタイミング」の場所へと記述する形ですね。
↓インサート方法記述サンプル
<?php
// データベース(apply_list)テーブルに新規挿入
global $wpdb;
$tableName = $wpdb->prefix . "apply_list"; //テーブル名を指定
$lastInsertId = $wpdb->insert_id; //IDをインクリメントするのに必要な処理
// 挿入する中身を設定
$arr_ins_data = array(
'apply_id' => $lastInsertId,
'apply_name' => $_POST['名前'],
'apply_mail' => $_POST['メールアドレス'],
'apply_desc' => $_POST['メッセージ'],
'apply_status' => '申込中'
);
// 整数か文字列かを指定 %dなら数字 %sなら文字列
$format = array(
'%d',
'%s',
'%s',
'%s',
'%s'
);
$wpdb->insert($tableName, $arr_ins_data, $format); //insertによって新規追加させる指定
?>
後は実際にメールを送ってみて、先ほどの「表示」の方でその内容が反映されてるか確認できれば成功。
これがうまくいけばもうDB操作は90%クリアしたようなものです。
データ更新の方法
新規追加ができるようになれば、後はそのデータ自体を自由に更新できるようにします。
例えば、やりたい事としては…
申込フォームからのメール
↓
データベースへそのメール情報を新規追加(↑さっきのやつ)
↓
こちらで申請を判断する間は承認待ちとなり、ステータスは「申込中」となっている
↓
許可が降り、「申込中」のステータスを「受理」へと変更させたい(今ココ)
↓
データベース内のステータスをいじる(ページ内で)
もちろん「phpMyAdmin」からならDBは自由にいじれます。
でもいちいちサーバー管理画面開いてDBページにログインなんてしてられないですよね。
そこで、制作した自分のそのサイト上で一覧表示されているページ内でそれらを操作できるように、更新する為のコード記述方法を紹介します。
【更新フロー】
まずは一覧表示させている画面内(PHPファイル側)で「変更用ボタン」を作ります。
これはSELECTで表示してる「foreach内」で1つずつに対してボタンを作っておくと楽です。
つまり受信したメール1個に対して、それ専用の1個の変更ボタンです。
セレクトボックス&フォームボタンという形でいいと思います。
さらにそのフォーム内に隠しデータとして他の値も入力させておきます。
例)
<form method='POST' action=''>
<input type='hidden' name='ID' value=" . $row->apply_id . ">
<input type='hidden' name='名前' value=" . $row->apply_name . ">
<input type='hidden' name='メアド' value=" . $row->apply_mail . ">
<input type='hidden' name='内容' value=" . $row->apply_desc . ">
…という形で含めておきます。
「申込中」か「受理」か「キャンセル」か…みたいなセレクトボックスのボタンを作成し、そのボタンが押された時の挙動として下記の変更の為の記述を用意します。
上記続き
<select name='ステータス'>
<option value=''>変更するものを選択</option>
<option value='申込中'>申込中</option>
<option value='受理'>受理</option>
<option value='キャンセル'>キャンセル</option>
</select>
<input type='submit' name='変更ボタン' value='変更'>
</form>
↓ボタンを押して更新させる記述サンプル
<?php
global $wpdb;
// どういう時に更新をするのかという指定は必ずする事
if(isset($_POST['変更ボタン'])) { //ボタンの「name」属性を指定
// ボタンのフォームで送信された内容を変数へ代入しておく
$APP_id = $_POST['ID'];
$APP_name = $_POST['名前'];
$APP_mail = $_POST['メアド'];
$APP_desc = $_POST['内容'];
$APP_status = $_POST['ステータス'];
// DBテーブル名
$tableName = $wpdb->prefix . "apply_list";
// 変更する値(アップデートさせるデータ)でステータスを指定
$dataName = array(
'apply_status' => $APP_status,
);
// 一致させる値の指定(アップデートさせるカラムの指定)
$whereName = array(
'apply_id' => $APP_id
);
// 整数か文字列かを指定(アップデートさせるデータ側)
$format = array(
'%s'
);
// 整数か文字列かを指定(アップデートさせるカラムの指定側)
$whereformat = array(
'%d'
);
// 投稿を更新
$wpdb->update($tableName, $dataName, $whereName, $format, $whereformat);
}
?>
これによってDB内容の「更新」ができます。
元々存在しているデータの塗り替えという事ですね。
流れとしては「取得したIDのデータ」を引っ張って来て、「そのIDに対してステータスを指定したものへ変更する」という処理が行われているサンプル例です。
データの削除の方法
最後に削除ですが、これも今までの応用となります。
今回は「,」カンマ区切りで複数指定ができるようなテキストフォームを作って削除ボタンで一気に消せる仕様にします。
例えばこういう削除用のフォームを作っておきます。
<form method="POST" action="">
<input type="text" name="applyID" value="">
<input type="submit" name="削除ボタン" value="削除">
</form>
テキストフォームの中には削除したいIDの数字を入力する仕様です。
イメージとしてはこんな形↓
↓ボタンを押して削除する記述サンプル
ちなみにaction指定ページはないので同ページを再読み込みする形です。
<?php
// データベース(apply_list)テーブルの指定されたIDを削除
// まずはお作法としてグローバル呼び出し
global $wpdb;
// どういう時に削除をするのかという指定は必ずする事
// 同ページでの読み込みになっているので「削除ボタンが押された時に」という指定が必要
if(isset($_POST['削除ボタン'])) { //削除用のボタンの「name」属性を指定
//複数指定の場合、カンマ区切りを分割して配列扱いにする
$APP_id = explode(",", stripslashes_deep($_POST['applyID'])); //テキストフォーム内の数字を配列として取得
// 取得した配列のIDをループで1回ずつ削除していく
foreach($APP_id as $val) {
$tableName = $wpdb->prefix . "apply_list";
$whereName = array(
'apply_id' => $val //取得した数字をIDとして認識させる
);
$format = array(
'%d'
);
$wpdb->delete($tableName, $whereName, $format);
}
}
?>
これで指定のIDのデータが1行ずつ削除可能となります。
5番と8番を消したければ、フォームに「5,8」とカンマ区切りで書いてボタンを押すだけです。
foreachを使ってループで指定の分だけ削除を回してる事によって複数指定ができます。
ちなみに全消しの方法もありますが、危険なのでミスらないように実装の際は要注意です。
まとめ
取り合えず基本的なオリジナルDBの使い方は以上となります。
前述した「CRUD」ですが、SQLで例えるとこうなります↓
作成 (Create) →INSERT
取得 (Retrieve)→SELECT
更新 (Update) →UPDATE
削除 (Delete) →DELETE
この4つの記述方法さえ使い方が分かればDBの操作を全てPHPファイル内で可能となります。
後は応用していくのみとなりますが、そこは各々の使い方次第でいろんな事ができると思いますので、案件によってベストな使い方にトライしてみて欲しいと思います。
例えば自作のカレンダーと紐づけて予約フォームなんかも可能かなと思います。
さらに応用して美容院や歯医者の予約フォームみたいなものも作れそうです。
イベントへの参加表明やチケット予約システムなんかもできるかもしれません。
簡易BBSやTwitterのような一言コメント残しなんかも作れると思います。
視聴者参加型のサイトには便利に使えそうなシステムとなりそうです。
その他にも使えそうかなと考えてる機能としては
・応募フォームの管理
・不動産サイトでの内見予約管理
・来店予約管理
・飲食店でのメニューオーダー管理
・カート機能を付けたサイトでの商品購入履歴管理
ちなみにユーザー毎に設置するオリジナルのDB追加の方法もありますが、それはまた別の作成方法となり、これはこれでまためんどくさいです。
あと、DBについての記事検索すると「PDO」というのが何度も出てくると思うのですが、今回はそれらには触れてないです。
※上記、ここで紹介した方法はセキュリティ面には触れてませんので、独自で追記設定する事を推奨します
では現場から以上です!
【参考サイト】
DBについて参考にさせていただいたサイト様です。
参考サイト① : http://blog.yukarien.com/tech/wordpress-db-access/
参考サイト② : https://hyperts.net/wordpress-db-create/
2843