掲示板の作り方#5 スレッド投稿のフォームをつくる
こんにちは。Suipediaです(∩´∀`)∩
前回はヘッダ、サイド、フッタを作りました。各種表示のカスタマイズについてもお伝えしました。
こんな表示でしたね。メインのコンテンツがないので、ページの縦幅がすごく狭くなっています。
今回はいよいよ本格的な掲示板づくりに入っていきましょう。
ページの構成からするとスレッドの一覧から作るのが筋ではあるのですが、表示するスレッドがないことには説明に差し支えるので、まずはスレッドの投稿から作ります。
では、まいりましょう!
今回のゴール
今回が終わるころにはこんな
画面が出来上がっている予定です。
がんばりましょうヾ(≧▽≦)ノ
スレッド作成ページへのリンクをつくる
まずはこれをご覧ください。
おつくりいただく掲示板サイトのページ構成です。トップページは前回作成しました。今回作るのはスレッドを新規に登録するページです。
ユーザの導線としては、まずトップページにアクセスして、そこから新規登録ページに遷移します。
つまり、トップページにスレッド作成ページに遷移するためのリンクが必要になります。まずはそれを作りましょう。
#3でお配りしましたbody.phpを開いてください。
7行目がまだコメントアウトになっていますね。ここを解除します。
前回、header.php、sub.php、footer.phpを配布しましてそれぞれ所定のフォルダに置いていただきました。
これらのフォルダはinclude_once()の引数に
$webroot."/src/parts/header.php"
という書き方をしていたので、
「srcフォルダの中のpartsフォルダに置くんだな」
ということがご理解いただけたと思います。
ですが、コメントアウトを解除していただく7行目は・・・
<?php //include_once("c.php"); ?>
このようになっていますよね。「どこのフォルダにc.phpファイルを置けばいいの!?」となるでしょう。
ここでまた新しい知識をご紹介します。
ファイルを指定するときは絶対パス指定と相対パス指定の2つがあります。この絶対、相対という言葉はほかの分野でも使いますよね。絶対評価、相対評価とか。
意味合いとしてはこれと同じです。
今回、c.phpファイル以外は絶対パスで指定しています。
<?php include_once($webroot."/src/parts/header.php"); ?>
これですね。まず、ここまで置き去りにしてきた$webrootについてお伝えしましょう。
$webrootは#3のときに
$webroot = $_SERVER['DOCUMENT_ROOT'];
こんな形で右辺の値を代入しました。ここでどんな値が代入されたかというと、実際には
C:/xampp/htdocs/bbs
というテキストをもっています。確認したい!という方はbody.phpに
このように処理を追加して、トップページをリロードしてみてください。
このように表示できます。で、実際の使用箇所では
$webroot."/src/parts/header.php"
このようにしていますね。$webrootとその後ろの文字列の間に「.」ドットがあるのが分かるでしょうか。
PHPではドットは文字列の連結に使います。システム開発には、今回みたいに変数がもってる値に続けて別の文字列を繋げたものを一つのテキストとして扱いたい場面がままあります。
なので、上記のコードは
C:/xampp/htdocs/bbs/src/parts/header.php
と同義です。
このファイルパスはエクスプローラーから辿った時、確実にheader.phpにたどり着けます。これが絶対パスです。ファイルを探す際の基準の場所が最も最上位のフォルダ(C:\)なんですね。
それに比べ
<?php //include_once("c.php"); ?>
は相対パスとして書かれており、ファイルを探す基準の場所は今いる場所です。
今いる場所・・・とはユーザがアクセスしているページです。厳密には、ユーザがアクセスしているフォルダです。
つまり!絶対パスと異なり、今開いているページによって参照先が変わることになります。
実際に手を動かしていきましょう。
body.phpの7行目のコメントアウトを解除してください。
この↑ようにしていただければOKです。
そして、c.phpファイルを用意しましょう。
index.htmlを選択した状態で新しいファイルボタンをクリックしてください。
ファイル名は「c.php」です。ちなみにこの「c」ですが、コンテンツ(contents)の「c」です。各ページのメイン部分のコンテンツを担当するファイルなので、この名前にしています。私の好みです(∩´∀`)∩。
で、おつくりいただいたc.phpに以下のソースを書いてください。
<section class="threadList">
<h3><b>新しくスレッドを立てたい方は<a href="/new/">こちら</a>。</b></h3>
</section>
↑このようにできればOKです。この状態で・・・
を開いてください。
「新しくスレッドを立てたい方はこちら。」が追加されました。ここの文言もあなたの好みにしていただいて大丈夫です。
リンク部分は
<a href="/new/">こちら</a>
こんな風に書いています。aタグはアンカータグと言い、別のページや別のサイトへのリンクを貼りたいときに使います。
この指定にも絶対パス指定と相対パス指定があるのですが、ここでは絶対パス指定をしています。最初が「/」スラッシュで始まる場合は同サイト内の絶対パス指定であり、最初のスラッシュは最上位のフォルダを示しています。
つまり、上記で指定したパスは最上位のフォルダにあるnewフォルダを指しています。
実は先ほどのinclude_onceの説明の中では最上位フォルダをc:\と説明しました。ここの詳細は割愛させてください。
aタグのリンク先を指定するときは#2でhttpd.confファイルに設定いただいたフォルダ(bbsフォルダ)が最上位フォルダになります。
これでスレッドの投稿ページへのリンクは作れたので、今度は遷移される側を作っていきましょう。
スレッド投稿ページの基盤をつくる
先ほど最上位フォルダにあるnewフォルダがスレッド投稿ページのパスだ、とお伝えしました。
まずはそのフォルダを作ります。
index.htmlを選択した状態で「新しいフォルダ」ボタンを押してください。
フォルダ名の入力枠が出るので、「new」と入力します。入力したらEnterキーを押しましょう。
今の時点ではフォルダ構成は
このようになっていればOKです。
では、newフォルダの中に以下のファイルをおいてください。
--2020/06/04追記--
このファイルを置いた後、サーバを再起動してください。
この.htaccessファイルについては後続記事のどこかでご説明いたします。
そして、index.htmlも置きたいのですが、それはトップページで作ったものをコピーしてきましょう。
トップページのindex.htmlファイル上で右クリックし、メニューからコピーを選択します。
そして、newフォルダの上で右クリックをし、メニューから貼り付けを選択します。
貼り付けをクリックすると・・・
このようになればOKです。赤線を引いた箇所はトップページのときと同様にページタイトルとしてheadタグ内のtitleタグに使用されるテキストです。
ここは「スレッドを立てる」とでもしておいてください。(あなたの好きにしていただいて大丈夫(∩´∀`)∩)
さらに、c.phpも作りましょう。ここまでと同じ要領で作ってください。
このように追加できていればOKです。
この状態で、トップページからリンクをクリックしてみましょう。
はい、ページが遷移できたと思います。タブのタイトルがスレッド投稿ページ用になっている辺りでちゃんと適切なページが読み込めていることを確認できますね。
これでスレッド投稿ページの基盤部分の作成は完了です。
初めての方には大変に感じたかもしれませんが、#3と#4で共通部分のソースを一元管理にしたおかげでとても簡単に済んだ、と感じてもらいたいところです( *´艸`)
では、ユーザに入力していただくフォームを作っていきましょう。
投稿フォームをつくる
今から作るのは・・・
この中央にあるフォームです。(アイコン部分はまだやりません)
ここから少しずつ険しい坂道になっていきますので、よろしくお願いします。
まず、ユーザに入力していただくフォームなのですが、これはこの掲示板システム内で2か所あります。
・スレッドの新規作成
・スレッドのレスポンス投稿
の2か所ですね。
で、若干の差異はありつつも入力していただく内容はだいたい同じです。なので、ここでも共通のソースコードを使いましょう。
newフォルダのc.phpファイルに以下のソースコードを書いてください。
<?php
$closeflg = 0;
$formTitle = "スレッドを立てる方は各項目に入力してね";
include($webroot."/src/parts/form.php");
//include("script.php");
//include($webroot."/src/script/iconScript.php");
?>
コメントアウトしている箇所は今はまだ不要なソースです。script.phpは#6で、iconScript.phpは#10で開放します。
前回までもやってきたように、またinclude_once()を使います。該当ファイルを作成しましょ・・・いや!つくるのはよしましょう。
以下のファイルを
src > partsフォルダに置いてください。
フォームを表現しているHTMLソースはまま複雑なのでファイルを配布しました。
フォームを表示する部分はプログラムを使っており、#3で少し説明しました関数も呼び出したりしてます。ためしに今の状態でブラウザをリロードしていただけますか。
はい、エラーになってしまいました。
Fatal error: Uncaught Error: Call to undefined function p()
これはですね。
p()という関数を呼び出すことができない!
という内容のエラーです。
ですので、ここからは#4でファイルだけご用意いただいたfunction.phpに関数を追加していきます。
今はこんな状態ですね。空っぽです。
先ほどのエラーメッセージの最後の行を見てみましょう。
C:\xampp\htdocs\bbs\src\parts\form.php on line 2
これはエラーの原因となっている箇所を示してくれています。実際に見てみると・・・
はい。p()という関数を使っています。まずはこの関数をfunction.phpに追加しましょう。
functioin.phpに以下のソースを追加してください。
<?php
/**
* プリント(出力)処理の簡略記載用
*
* @param $str 出力する文字列
*/
function p($str){
print $str;
}
?>
ここまでの説明の中でPHPプログラムから画面に文字を出すときは
<?php
print '出したい文字をここに書く';
?>
という書き方をしてきました。ただ、私この書き方あまり好きではないんですよね汗。だからprintのpを拝借して独自に用意したp()を使っています。
処理内容はいたって簡単、引数に受け取った値をprintで出すだけです。
この実装ができた状態でブラウザをリロードしてみましょう。
画面の表示が少し進みました!ここで補足情報なのですが、PHPプログラム中にエラーが出たときはそれ以降の描画も中断されます。
なので、上図もサイドメニューとフッタの表示がありません。
さて、またエラーですね。ここからの流れはエラーを発見→エラーを解消→画面描画→エラーを発見→エラーを解消→・・・と繰り返していくのですが、くどいですよね。いちいちこの流れをやっていると。
今必要な関数をささーっと紹介&解説していくのでこれに倣ってfunction.phpファイルに追加していってください。
/**
* レスポンスを返すフォームかどうかを返す
*
* return レスポンスの返信フォームならtrue,そうでないならfalse
*/
function isResponseForm(){
return strstr(getRequestURL() ,"/thread/");
}
まずはこの関数です。ファイルの方は・・・
このようになっていればOKです。こんな感じで関数を追加していきます。
このisReponseForm()は今表示しているフォームがレスポンス用かどうかを返します。先ほど、スレッド作成とレスポンス登録で同じフォームを使うけど少し差異がある、という話をしましたよね。
その差異の部分を制御するための関数がこれです。URLの内容でどっち用のフォームかを判断します。
今アクセスされているページのURLに「/thread/」が含まれていたらスレッド登録(true)、そうじゃなければレスポンス登録(false)を呼び出し元に返します。
次に、以下の関数を追加してください。
/**
* URLのドメイン以降を取得する
*
* return ドメイン以降
*/
function getRequestURL(){
return $_SERVER["REQUEST_URI"];
}
今アクセスしているページのURLの一部を返す関数です。これは先ほどのisReponseForm()の中で使われています。
function.phpに追記していく関数はそれぞれ独立しているので、順番はなんでもいいです。
次に以下の関数を追加しましょう。
/**
* 新しいスレッドを作るページかどうかを返す
*
* return 新しいスレッドの登録フォームならtrue,そうでないならfalse
*/
function isNewThreadForm(){
return strstr(getRequestURL() ,"/new/");
}
こちらは先ほどのレスポンス用フォームかどうかを判定する関数と対になる存在です。
URLに「/new/」が含まれていたらtrueを返しそうでないならfalseを返します。
ここまでで、trueだとかfalseだとかって言葉が急に出てきたのですが、これについてはPHPの文法であるIF構文(いふこうぶん)の説明をするときに改めて触れます。
ここまでの関数が追加できましたらブラウザをリロードしていただけますでしょうか。
このようになればOKです。
ではですね、この後は先ほどチラッと言葉を出したIF構文をお伝えして終わりにします。
IF構文のご紹介
プログラミングの重要な文法、IF構文をご紹介します。
先ほどのform.phpファイルは入力項目を画面に出すかどうかの表示を制御している箇所があるので、文法を伝えた後にそこを例に使い方をお伝えします。
まず基本的な文法ですが
<?php
$nowYear = 2020;
if($nowYear == 2020){
print '今は2020年です';
}
?>
これですね。ifの行になにか式を指定し、その結果がtrueならその{}の中の処理を実行します。
上記で言うと、変数$nowYearが2020かどうかを判定します。このif()に指定する式はtrueかfalseを返すものを書くようにし、比較する場合は「==」を使います。正ならtrue(とぅるー)、否ならfalse(ふぉるす)を返します。
「==」は「ダブルイコール」と読みます。
if文はもう少し拡張することができ、例えば2020年じゃなく2021年だった時の処理を書いたり、2020年でも2021年でもなかったときの処理を書くという記法もありますが、それは#6で実装があるのでそこで紹介します。
次は、form.phpの例をみていきましょう。
form.phpの19行目付近を見てください。
ここではif()の中にisNewThreadForm()という関数を指定しています。
そうです、ここには関数を呼び出すこともできるんです。ただし、それはある条件をクリアしているときにのみできる方法。。その条件が・・・
trueかflaseのいずれかの値を返す関数であること
です。
isNewThreadForm()を改めて見てみると・・・
function isNewThreadForm(){
return strstr(getRequestURL() ,"/new/");
}
こんなことをしています。ちょっとわかりにくいかもしれませんね。
まず、strstr()というPHPの標準関数を使って、現在のURLに「/new/」が含まれるかどうかを取得しています。そして取得したものをそのままreturnしているんですね。returnは指定した値を呼び出し元に返す働きがあります。
もう少し段階を踏んで書くと、
function isNewThreadForm(){
$result = strstr(getRequestURL() ,"/new/");
return $result;
}
ということになります。この
strstr(getRequestURL() ,"/new/");
自体が「true」か「false」そのものなんですね。だから
function isNewThreadForm(){
return strstr(getRequestURL() ,"/new/");
}
このようなそのまま返す書き方ができます。
呼び出し元の記載に戻りましょう。
タイトルはスレッドを作るときにのみ必要な項目です。ですので、上記のようなif文を付与することで、スレッド作成の時にだけ画面に表示されるようにしています。
trueを返さなかった場合、{}の中の処理群は実行されないため、タイトルの入力項目は表示されないことになります。
実際の画面確認はレスポンスフォームを表示するときに譲りましょう。
その次の名前項目はスレッドの作成でもレスポンスの返信でも必要なのでこのような分岐処理をせずに書いています。
おわりに
今回はスレッド登録のUI(ユーザインターフェース)を作りました。
肝心のフォームのHTMLソースは出来上がったファイルをそのままお渡ししたので印象が薄いかもしれません。
しかし、掲示板の開発はプログラミングのロジックやデータの持ち方等々の方が重要なので、これはこれでヨシとしてください。
今回新しく学んだのは、絶対パス、相対パス、IF構文の辺りです。どれも基本的な知識でwebプログラミングには欠かせません。
ユーザが入力する部分は今回できました。となると次回は入力いただいたデータを実際に登録するところですね、そこをやりましょう。
今回もお疲れ様でした。ゆっくりお休みになってくださいヾ(≧▽≦)ノ
ありがとうございました(∩´∀`)∩。