1 想定ケース
PHPでメンバーがログインしてメッセージを投稿するという機能を実装すると想定。投稿データはpostsというDBに保存します。
『よくわかるPHPの教科書 【PHP7対応版】 』(マイナビ出版)p267ページで躓いたことによる学びをメモします。
1-1 投稿を保管するデータベース
カラム | 位置付け | 設定 |
---|---|---|
id | ID | INT、プライマリーキー、オートインクリメント |
message | ユーザーが投稿したメッセージ | TEXT |
member_id | ユーザーID | INT |
reply_post_id | 投稿が別の投稿への返信だった場合、その別の投稿のID | INT |
created | 投稿日時 | DATETIME |
reply_post_idは、投稿が返信だった場合のみ発生するので、これだけ必須項目ではないという状況です。そのようなカラムをどう処理するかという記事です。
1-2 投稿をDBに登録するPHPのコード
if (!empty($_POST)) {
if ($_POST['message'] !='') {
$message = $db->prepare('INSERT INTO posts SET member_id=?, message=?, created=NOW()');
$message->execute(array(
$member['id'],
$_POST['message']
));
header('Location: index.php'); exit();
}
2 問題
投稿が返信ではない場合、つまり通常の投稿の場合、上記のコードではエラーが起きて投稿がDBに保存されません。
試しにphpMyAdminで同じSQL → INSERT INTO posts SET member_id=?, message=?, created=NOW(); を実行すると、下記メッセージが出ます。
MySQL said:
#1364 - Field 'reply_post_id' doesn't have a default value
このことから「reply_post_idが空ですよ〜」というエラーが発生していると推定できます。
3 解決に向けて
3-1 3つの解決策
(1) SQLでreply_post_idに適当に値を入れる(下記コードご参照)
$message = $db->prepare('INSERT INTO posts SET member_id=?, message=?, reply_post_id=0, created=NOW()');
(2) DBの設定でデフォルト値をNoneではなくAs defined : にして適当にデフォルト値を入れておく。(0とか)
(3) DBの設定で、Nullにチェックを入れておく。(デフォルト値をNULLにすることと同義。)
3-2 最善策は?
reply_post_idは、返信する場合にのみ、返信先のポストのidを入れる項目です。つまり返信でない通常の投稿の時は、値が必要ありません。よって、このケースでは3を選択するのがベストという結論に至りました。
0などの意味のない値をDBに入れることは混乱にも繋がるのでなるべく避けた方がいいそうです。例えば、他の人がそれを見た時に「0って何?どういう意味?」と混乱させることになりかねないからです。
最後に
初めてのqiita投稿になります。もしご指摘などあれば頂戴できますと幸いです。
ありがとうございます。