HTMLやPHPで掲示板を作る方法

この記事は14分で読めます

自分用メモ

随時追記していく

※参考:ポートフォリオのジャンルや制作過程、注意点や必要な機能
※参考:ProgateでHTML & CSSを学習
※参考:ProgateでPHPの学習

目次

掲示板の作成方法 その1



掲示板はお問い合わせフォームと異なり、
データを外部に保存する仕組みがある。

外部にデータを保存する方法は2種類ある。
①テキストファイル
②データベース

今回は①のように、テキストファイルで保存されている。
小規模なシステムでは、この方式が用いられている事がある。
単純でデータ量が少ないデータを保存する場合は向いている。

ただ基本的には②が採用されている。

掲示板の作成方法 その2



以下の4つに分けて処理を記述する。

①変数とエラーメッセージの定義

→isset、trimを覚える
※画像:
trimは、文字列の最初と最後の空白を取り除く関数である。
プログラムでは、空白があるとエラーの原因になるので困る。

以下のように記述する。
trim(文字列,”取り除く要素”)

()内に、空白を取り除く文字列と取り除く要素を指定する。
「取り除く要素」の部分は省略が可能。

パラメータを指定することで、
改行など特定の要素のみを削除することも出来る。


②入力のエラーチェックと書き込み

→fopen、fwriteを覚える:ファイルに記述するやつ?

ファイルの読み書きを行うにはfopen関数が必要。
ファイルやURLを開いてくれる働きがある。
fopenでファイルを開いた後、指定の条件を通して処理し
fclose関数で開いたファイルを閉じるのが一連の流れになる。

fopen基本構文は以下の通り。
$変数名(ファイルポインタ) = fopen(“開きたいファイル名”, “オープンモード”);

オープンモードとは、fopen関数でファイルを開く際に、
どういう様式(モード)でファイルを開くかを指定するもの。
主なオープンモードは以下の通り

★書き込み専用でファイルをオープン
“w” ファイルポインタの位置は先頭
“x” ファイルポインタの位置は先頭
“c” ファイルポインタの位置は先頭
“a” ファイルポインタの位置は末尾

★読み込み専用でファイルをオープン
“r” ファイルポインタの位置は先頭

ファイルポインタとは、
どこからファイルに読み込みや書き込みをするかの始まりの位置。
既存の内容に追記したい場合は、ファイルポインタが終盤にある
“a”を指定しないと、上書きされるので注意する。


文字列をファイルに書き込むにはfwrite関数を使う。
fwrite関数は、fopen関数やfclose関数と併用して用いられている。

書き方は以下の通り。
ファイルポインタは、書き込むファイルをfopen関数で開いたものが入る。
fwrite(ファイルポインタ, 書き込む文字列 (,文字列の長さ(省略可) ) );


③テキストファイルからの読み込み


→DBだと、この表示は書き換える必要ある?
→while文、fgets、explode、連想配列を覚える

プログラムへ入力されるデータはキーボードだけでなく、
外部ファイルからも読み込む事ができる。
選択肢としては、1行ずつ読み込んで処理する関数(fgets)と、
全体のファイルを一度に読み込む関数(file_get_contents)がある。

fgetsの書き方は以下の通り。
文字列 = fgets(ハンドル)

ハンドルはファイルの処理位置を示していて、
処理位置を進めることで開いたファイルの先頭から順に
読み込んだり出力したり出来る。



④HTMLへの表示

→foreach、endforeachを覚える

その3 エラーチェックとファイル書き込み



①変数の定義

PHP上で使う変数は、あらかじめ定義しておく必要がある。

プログラミングとは、変数に何かしらのデータを入れて、
それを処理したり、画面に表示したりする行為である。
このデータが入る変数をあらかじめ用意しないと、エラーが発生してしまう。

isset関数は、変数に値が入っているかをチェックする関数。
変数に値がセットされていて、かつNULLでないときにTRUE(真)を戻り値として返す。
isset関数は、if-else文と合わせて使われる事が多い。
 TechAcademyマガジン
PHPのisset関数で変数に値がセットされているかを確認する方法【初心者向け】
https://techacademy.jp/magazine/11410
プログラミング初心者向けにPHPのisset関数を使って変数の中身が存在するかどうか確認する方法について解説しています。変数に値が入っていた時、入っていなかった時の処理を簡単に行えるので、ぜひ今のうちに理解しておきましょう。

以下のコードはショートハンドで記述している。
これは、クリックボタンが押された場合はname(comment)にデータを入れ、
そうでない時(一番最初に画面を読み込んだ時)は空白を入れる、という処理である。

②エラーチェック

未入力データのチェックを行う。
この処理は今後も行うで、慣れておくこと。

③ファイルポインタ

ファイルの入力や出力を行う際に必要となる、本の「しおり」みたいなもの
この「しおり」に入力や書き込みをすることで、
実際のファイルへの入出力が出来るようになる。

「$fp = fopen(“data.txt”, “a”)」で、ファイルポインタを取得している。
最後の「a」は「追加の書き込み」という意味がある。

次の「fwrite($fp, $name.”\t”.$comment.”\n”)」では、
実際に取得できたファイルポインタに書き込みを行なっている。
「fwrite(ファイルポインタ、書き込み内容)」というのが図式。

その4 ファイル読み込みとHTML表示



①テキストファイルの読み込み

テキストファイルへの書き込みはfwriteだが、
読み込みの場合はfgetsという関数を用いる。

$fp = fopen(“data.txt”,”r”)
「r」は、正規表現では「復帰」という意味。
 MDN Web Docs 
正規表現パターンの記述
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Writing_a_Regular_Expression_Pattern
正規表現パターンは、/abc/ のような単純な文字、または /ab*c/ や /Chapter (\d+)\.\d*/ のような単純な文字と特殊文字との組み合わせからなります。最後の例では記憶装置として使われている丸括弧が含まれています。パターンのこの部分でなされたマッチは後で使用...


②配列への格納

「配列の操作、処理」と「オブジェクト指向」の2つは、
プログラミングを行う上での2大テーマだと言える。

テキストファイルから文字を取得したら、これを配列に入れる。
そのためにはexplodeで「分割」を行う必要がある。

「$tmp = explode(“\t”,$res)」という処理は
$resという文字列を\t(タブ)で区切り。配列にします、という処理。

「\t」は、正規表現では「タブにマッチする」という意味。

★多次元配列への格納
掲示板の書き込みは1つでなく、通常多数であることが一般的。
そのため多次元配列に格納する必要が出てくる。
多次元配列とは、配列の中に配列を入れるタイプのやつ。


PHPの配列は、配列の中に配列を格納して
入れ子構造(ネスト)にする事が可能。
[](角括弧)を[][][]と連ねることで、多次元配列を作成する事が可能となる。


③HTMLへの表示とforeach

PHPで一番出てくる関数はforeachなので、
この配列の処理に慣れてない場合は、何度も復習すること。


①forの書き方

実務で一番多い繰り返は、配列の処理である。
具体的には、以下のように使う。
(分かりやすいように空白を入れている)

ただ、配列の要素が多いと数えるのが面倒なので、
count関数で数えて対応する事が多い。

②foreachの書き方

foreachを使うのは、forには以下の問題点があるから。
→スタート、ゴール、カウントアップを自分で書く必要がある。
→配列の要素数を数える処理が必要になる。

こうした点を、foreachはカバーしている。

foreach(ループさせる配列(変数) as キー => 値)
これが基本。

「キー」は$keyが、
「値」は$valueが
それぞれ使われる事が多い。
→「キー」は不要だが、「値」は必ず必要。

③多次元配列とforeach

実務で使われるのは、多次元配列の中に連想配列が入っているパターン。
人間が普段扱うデータは、このケースが圧倒的に多い。

コードは、以下のようになる。

④補足:jsの場合

※参考:日記0827。プログラミング学習⑥forとforeach

⑤endforeachについて


foreach文は、開きカッコ「{」をコロン「:」に、
閉じカッコ「}」を「endforeach;」に変更する事ができる。
書き方は以下の通り。

foreach (配列 as 変数):
//処理文
endforeach;


値に加え、キーも取得する場合はこちら。

foreach (配列 as 変数A => 変数B) :
//処理文
endforeach;


変数Aには「$key」が、変数Bには「$value」が、
例文のコードではよく用いられている気がする。



その5 掲示板の作成方法 まとめ



①掲示板学習で学べること

①外部装置へのデータ格納
一番大きなポイント。
HTMLでサイトを作る場合、文章や情報はHTMLソースの中に書かれるが、
PHPなどで作るWebアプリの場合、
ソースの中に情報はないことが一般的。

なので、情報を格納しておく外部装置が必要。
テキストファイルを使うケースと、データベースを使うケースがある。
今回は最初なのでテキストファイルを使っているが、
ある程度の規模になるとデータベースを使う。

②ファイルポインタ
ポインタとは、外部装置からデータを読み込む時に必要なるもの。

ファイルポインタとは、どこからファイルに
読み込みや書き込みをするのかの始まりの位置。

③配列への格納と操作
求めるデータを配列にしっかり格納して、表示できるか。
人間がデータを認識するのは、「配列」という形である。

配列の処理はとても重要。
プログラマーである以上、配列処理のような事は毎日やるようになる。
早い段階でこの処理に慣れるのが重要。

※参考:日記0827。プログラミング学習
※参考:日記0831と0901
※参考:日記0902

★配列、連想配列、多次元配列

配列操作はPHPに限らずプログラムにおいて超重要。
配列の操作ができないプログラマーは、
かわいくないアイドルや体力のないアスリートのようなもの。

jsのオブジェクトとPHPの連想配列は同じ

ただし、jsではキーと値の間に「:」が来るのに対し、
PHPではキーと値の間に「=>」が来るので注意。


連想配列では、値に「キー」というラベルのようなものを付ける。
キー => 値」となってるのが基本。
キーを付けておけば、後で見返したときに何のデータか分かる。

この画像のように、連想配列は縦に書くのが望ましい。
データが増えたときに横にずらずらと書くと見にくいから。

値の追加や変更も可能。以下のように書く。

配列の操作は簡単に見えがちだが、
実際に操作をすると難易度が上がるので注意。



多次元配列は、配列の中に配列を入れるもの。
エクセル型配列」と言える。以下のファイルを保存するには…

以下のようなコードを用いる。
→連想配列を1つの塊として配列の中に入れている、という感じ。

最後の列では、カンマ「,」が無いので注意。
→また、コロン(.)も間違いがちなので注意。
出力に関しては、[]が二重になっている。

一括追加する方法(大きな配列の中に、小さな配列を一括で入れる方法)には、
次の番号(この場合は3番目)を入れる方法もあるが、

通常は、わざわざ何番目ということを調べるのが面倒なので、
大きい配列の中に小さい配列を入れる書き方をするのが一般的。






②掲示板機能へのカスタマイズ

①どのような機能を追加するべきか?
・項目をさらに追加し、それぞれにエラーチェックを行う
・ログインしたらこのページに入るようにする
・自分の記事は編集、削除ができるゆおになる
・1ページ10記事にして、下に1,2,3とリンクを付ける。
・記事を検索できるようにする

※参考:ウェブカツWebサービス部

②ソースとの格闘プロセス
・この機能どうやるんだろう?と悩む
・色々なキーワードで検索したり、本を読んであれこれ調べる
・見当がついた段階で実際にソースの中で試したり、推測する
・動く(動かない場合は最初に戻る)

データベース編その1 データベースとは



エンジニアの世界ではデータベースというと
大量のデータの格納、検索、挿入、編集、削除を
高速に行う専用のソフトウェア
」と定義されている。

エクセルは小規模で単純なデータ管理には向いているが、
数万件のデータを入れるとかなり重くなる。
もとが表計算ソフトなので、大量のデータを処理するのには向いてない。

MySQLはCUIで操作する。
GUIを使う方法もあるが、慣れるとCUIの方が早い。
また、MySQLのGUIは使えない場合もある。

データベース編その2 MySQLログイン編



普段、データはExcelで管理しているが、
今後は出来るだけMySQLで管理するように練習する。

MySQLには、ユーザー登録しなくても
最初から使える「rootユーザー」というものが存在している。

rootユーザーは、MySQLの中で一番偉いユーザーである。
MySQLでは様々なデータを扱う事になるが、
ユーザーによって見ることができる情報の範囲は異なってくる。
rootユーザーでログインすると、全てのデータを見れるので危険。
見てはいけないデータを見てしまう危険性があるし、
もっと怖いのはデータを破壊してしまうこと。

データベース編その3 データベース作成編



・データベースの作成:
create database データベース名 default character set utf8 collate utf8_general_ci;

・テーブルの作成
create table データベース名(
id int not null auto_increment primary key,
name varchar(20),
comment text
)

MySQLでデータを管理するには、
「データベース」と「テーブル」の概念を理解する必要がある。
ここで言うデータベースは、プロジェクトファイルのような感じ。
ある1つのプロジェクトの単位で作るデータの集合体を
「データベース」という。

①データベースの作成

MySQLでデータを扱いたい場合は、
まずこのデータベースを作成する必要がある。

データベースはphpMyAdminで作れる。
「テーブルを作成する」の項目から作ってもいいし、
SQL文を打ち込んでもいい。

②ユーザーの作成

→ウェブカツの動画見た方がいいかな?

MySQLでデータベースの作業をする時は、rootユーザーではなく
特定のデータベースだけを見れるユーザーを作成するのが一般的。

③テーブルの作成

MySQLで、データを格納するには
「テーブル」という表を作る必要がある。

テーブルを作って、その中にデータを入れていく事になるが、
「入れるデータのタイプ」を事前に決めておく必要がある。
(例:数字を入れるのか、文字を入れるのか、日付を入れるのか…等)

この「入れるデータのタイプ」は、一度決めると
別の形式のデータは入れる事が出来なくなる。

具体的には以下のデータのタイプがある。
・数字(int)
・文字数が決まった文字列(varchar)
・長文(text)
・日付(timestamp)

文字(varchara)と長文(text)の違いとしては、
前者の「文字」が名前、住所、電話番号、郵便番号といった
「ある程度長さが決まっている」点があ挙げられる。
一方、後者の「長文」はお問い合わせフォームの
コメント欄のように、長さの制限がない。

④プライマリーキー

次にMySQLで抑えるのが、そのデータを識別するためのid。
生徒番号や社員番号など。
こうした番号がないと、それぞれのデータを識別できない。
(名前だと同姓同名がいて、かぶる可能性がある)

プライマリーキーの特徴は以下の3つ
・他のデータと重複しない
・変更ができない
・どのデータにも必ず振られる

⑤実際のテーブル作成

今回の掲示板の場合、以下の3つが必要。

・書き込みデータを識別するためのid
→数字(int)であり、プライマリーキーの性質を持つ。
→自動で「+1」追加される。(AUTO_INCREMENT)

・書き込みをした人の名前のname
→長さの決まった文字列(varchar)

・書き込み内容comment
→長さが決まっていない長文(text)

データベース編その4 SQL編



①CRUDについて


・データを挿入:insert into テーブル名(カラム名1, カラム名2) values(’値1’, ‘値2’);
・データを検索:select カラム名 from テーブル名 where 条件式;
・データを更新:update テーブル名 set カラム名 = “変更したい値” where 条件式;
・データを削除:delete from テーブル名 where 条件式;

insert select update deleteの4つはは「CRUD」とも呼ばれる。
→insert:Create(生成)
→select:Read(読み取り)
→update:Update(更新)★そのまま
→delete:Delete(削除)★そのまま

CRUDは、Webアプリケーションで実装する必要のある
主な機能を列挙したものだと言える。

・作る
・検索する
・書き換える(更新する)
・削除する


CRUDは、ほぼ全てのコンピュータソフトウェアが持つ
永続性の4つの基本機能のイニシャルを並べた言葉である。
こうした昨日は非常に基本的なので、一纏めで解説されることも多い。


selectで検索する場合、whereを付けないと
特定のカラムのデータを全部引っ張ってきてくれる。
whereは、欲しいデータの条件付けをしている。


update文のポイントは、whereを忘れないこと。
これを忘れると全部のデータを一気に上書きしてしまう。

データベースはExcelと異なり、気軽にCTR+Zで操作を戻す事ができない。
ケアレスミスを防ぐために、whereを書いてからupdateを書くのがいい。


②データの削除2パターン

削除には「データ自体を物理的に削除する」方法と、
「削除してみるようにみせる」という方法の2つがある。

①データを物理的に削除する(物理削除
データを完全に消すこと。
やる場合は、updateの時と同様、where句を忘れないようにする。
もし重要な処理を行う場合はバックアップを必ず取ること。

②データを削除しているようにみせる(論理削除
windowsのゴミ箱が好例。
データ自体は消えておらず、このファイルの中に入ったら、
削除されたものとみなす(仮削除扱い)といった感じ。
データベースでの削除も、この手法を採用してる事が一般的。

データベース編その5 PHP-MySQL連結編



今回の掲示板の仕様は以下の通り
・入力欄は名前とコメントの2つのみ
・未入力があれば「名前とコメントを記入してください」と赤字で出力
・未入力でない時は「書き込みが成功しました」と黒字で出力
・入力されたデータは常に下に表示

ポイントとして以下の点が挙げられる。
・PHPとデータベースの接続
・エラーチェック
・SQLをPHPにどう渡すか
・SELECT文の受け取り方

PDOとmysqliの比較

https://qiita.com/mpyw/items/b00b72c5c95aac573b71
①PDOクラス
・オブジェクト指向型のみをサポート

★メリット
・動作が早い
・エラーを例外としてスロー出来る。
・「プリペアドステートメント=結果セット」であり、mysqliクラスと比べ初心者にもわかりやすい。
→プリペアドステートメント:SQLを使ってDBへ通信に使われる値をサニタイズする仕組み。
・プリペアドステートメントで名前付きプレースホルダが使える。
→プレースホルダ:値をバインドする(挟み込む:bindValue)仕組み。
・他のデータベースへ乗り換える際、書換が簡単。

★デメリット
・プリペアドステートメントで型を指定しながら複数のバインドが同時にできない。

②mysqliクラス
・手続き型(関数)とオブジェクト指向型(クラス)の両方をサポート

★メリット
・動作が非常に早い
・(手続き型の場合は)mysql関数からの書き換えが容易。
・マルチクエリが使える。1回の関数コールで複数のクエリが実行できる。
・エラーを例外としてスロー出来る。

★デメリット
・多機能なので初心者が混乱しやすい。


データベース編その6 まとめ編



①PHPとデータベースの接続


ウェブカツのPDOとは異なり、最初からDBへ繋いでいる。
接続できない場合は、50〜52行目にある
「データベースの接続に失敗しました」が表示される。

if以下の処理は、$linkにMySQLの接続情報が入っていたら…という意味になる。
(falseでない場合)
→trueでないので注意

②エラーチェック


投稿データの有無(未入力がないか)をチェックする。

※ウェブカツでは、emailの形式にマッチしてるかや、
パスワードとパスワード再入力が一致してるかをチェックしているが、
この掲示板は「名前」「コメント」のみなので、こうした機能は必要ない。

③SQLをPHPにどう渡すか


投稿があった場合、INSERT文を発行する。

PHPからMySQLに接続を行う場合は、
まずSQLを作り、それからMysql_queryで
MySQLにSQL文を渡す、といった手順を踏む事になる。
→作成したSQLを「$query」に格納した上で、「musql_query」で実行している。

上記の例では、INSERT文を行ごとに分けて書いている。
横1行で書いても問題はないが、行ごとに書いた方が
構造が分かりやすいし、後で修正があった場合も楽になる。

作成したSQLを「mysqli_query」という関数の中につなぐと、
書かれたSQLが実行される。
そして、成功不成功によってメッセージの内容を変更する。

SQLの投げ方は以下の通り

ウェブカツ(PDO)のケース

ウェブカツ(PDO)では、PHPからMySQLに接続を行う過程で、
MySQLにSQL文を渡す方法として、「->prepare」や、「->execute」を用いている。
作成したSQLを変数に格納して、「=>execute」で実行している。

このサイトではINSERTとSELECTが一緒に用いられているが、
ウェブカツではユーザー登録にINSERTが、
ログインにSELECTが用いられており、分かれている。

ウェブカツでは、SQL実行時に
「:email => $email」
「:pass => $pass」
といった形式を用いてる。
この形式で書くことで、その箇所に値を後から突っ込む事ができる。
このような、SQL文に後で値を挿入できる箇所を作って、
後から値を挿入して最終的なSQL文を作り上げる仕組みを、プリペアドステートメントという。
→後から値を挿入するとは、値をSQLに挟み込む(バインドする)事なので「バインド機構」とも言ったりする。

PDOは、PHPからデータベースへ接続するためのオブジェクト。
DBへ接続するためのオブジェクトを作っている。
PDOを理解するには、クラスと例外処理の基礎知識が必要となる。

④SQLインジェクション対策


mysqliでは、以下の構文がインジェクション対策になる。
mysqli_real_escape_string($link ,$name

作成したSQLを「mysqli_query」という関数の中につなぐと、
書かれたSQLが実行される。

⑤SELECT文の受け取り方


SELECT文の基本はINSERTと同じで、
mysql_queryでMySQLに問いかける。



簡単な掲示板を作る方法と心構え



以下の3つが実装出来ていれば、掲示板と言えるものが出来る

①内容に書き込んだ「文章」と「名前」をセットにして記録する
②送信ボタンを押すと①の機能が実行される
③記憶されてる内容(文章、名前)を表示欄にすべて表示する

「まずは最低限動くものを」という考え方が大切
いかに最速で動く段階まで到達できるかを重視する

必要な技術に関しては、テキストファイルに全ての情報を記録する形でOK
HTMLとPHPが動いて、記録用のテキストファイルを用意できる環境であれば
ローカルでもリモートでも何でもOK
(データベースやセキュリティ対策は不要。ただ本格的な掲示板を作りたいなら必須)

「掲示板の設計」について深掘りしたいなら以下を参照


どのように掲示板を組み立てるか


①ファイルに書き込みを記録する

まずはHTMLで書いたフォーム(=掲示板)に記入された内容をPHPに投げる方法を確認する
HTMLでformタグを使ってフォームを作る方法は以下を参照


またPOST送信、GET送信についても理解する必要がある
詳細は以下を参照


②PHPのファイルに書き込む

やりたいことは、ファイルに掲示板で投稿された名前と内容を記録すること
fopen関数、fclose関数などを使う。

③テキストファイルの情報を表示する

fget関数、explode関数、while文などを使う

PHPのセキュリティ対策について


上記の掲示板は、全体の視認性や理解のしやすさを重視しているので
セキュリティ対策を一切施していない

そのため、不特定多数の利用が想定される場所で公開すると
あっという間にXSS(クロス・サイト・スクリプティング)や
CSRF(クロス・サイト・リクエスト・フォージェリ)の餌食になる

CSSで色を施したり、XSSやCSRFの対策を施したいなら、
以下の記事を参考にする


2ch風掲示板の作成について


2chのデータは4階層構造になっている

①カテゴリー
2chの掲示板は、ニュースや食文化、ネット関係といった
「カテゴリー」と呼ばれる大きな分野単位で区切られている

②板
カテゴリーは、さらに「板」という細かいジャンルで区切られている

③スレッド
1つの板の中に、沢山の掲示板が設けられている
2chでは掲示板のことを「スレッド」と呼ぶ

④レス
2chでは書き込みのことを「レス」と呼んでいる

まずはMySQLで、
①カテゴリー②板③スレッド④レス
を格納するテーブルを用意する。

①カテゴリー:bbs_category
②板:bbs_board
③スレッド:bbs_board
④レス」bbs_response



備忘録メモ


上は「データベースを含んだ掲示板」と言ってたので、
HTMLとPHPのみで掲示板を作ったら、
DBも含めたページを作るべし。

DBを含めた掲示板が作れたら、次はWebサービスを作ってみるといいかも
※参考:Webサービスを作るには?必要なことや具体例など


  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

管理人紹介


21世紀、より良い人生を歩むための個人事業主による備忘録メモです。固定観念にとらわれず、日本や世界の深淵に触れ、自由快適な人生を歩んでいく事を大切にしています。