PHP応用編

掲示板を作る

1. 設計と準備

 応用編2つ目は簡易掲示板の制作です。これまで学んできたことを踏まえて作りますのであまり凝ったものはできませんが、よくありそうな簡易掲示板を作ります。
 ログインIDを管理してアクセス制御したり、連続投稿を防止したり、画像を貼り付けたりする高度なものは、各自勉強して作って下さい。ここで作るのはあくまで簡易掲示板です。
 掲示板の仕組みは、メッセージを受け付ける入力欄や送信ボタンを表示すると同時に、過去に投稿されたメッセージを保存しておいて、アクセスがあるたびにそれを読み出して表示することです。利用イメージとしては、掲示板でこれまでのメッセージのやり取りを見つつ投稿内容を入力して送信。すると確認ページで「内容はこれでいいですか」と表示されるので、OKとして投稿内容を保存しつつ元のページを表示する、といった具合です。画面構成は、掲示板を表示しつつ投稿を受け付けるページ、投稿内容の確認ページ、完了ページ、という形になるでしょう。
 ですので、ここで準備しておくファイルは4つ。掲示板メインページのファイルと、確認ページのファイル、投稿完了ページのファイル、そして掲示板データを保存しておくためのデータファイルです。

SPONSORED LINK

 これまで同様、phpkisoフォルダにあるひな形ファイルhina.htmlを[Ctrl]+[c]でコピーし、[Ctrl]+[v]を4回やるとファイルが4つできますので、それぞれouyou02a.php、ouyou02b.php、ouyou02c.php、ouyou02.txtと名前変更して下さい。今回は「~.html」はありません。phpプログラムを含むファイルは「~.php」です。
 ここではまず、ouyou02c.php以外の準備をしましょう。ouyou02a.php、ouyou02b.php、ouyou02.txtをテキストエディタ(Terapad等)で開き、以下のように編集します。応用編なので「■■■」で伏字にしてあります。「■■■」が3文字とは限りませんので何が入るか考えてみて下さい。またouyou02.txtはすべて削除して上書き保存して閉じて下さい。

  ouyou02a.php
  

  ouyou02b.php
  

 一応の説明を。まずouyou02a.phpです。PHPファイルですが今のところ内容はHTMLです。後でPHPスクリプトを追加します。やってることは簡単。<form>でデータを受け付け、postメソッドでデータを送信できるようにしています。「■■■」も簡単でしょう。
 次にouyou02b.phpです。コメントにも書いてありますが、PHPスクリプトのところ。postメソッドで送られてきたデータを受け取って無害化して変数に入れています。「■■■」わかりますか?ここでは、無害化の関数の中に、postメソッドの受取り変数を直接設定しています。PHP基本編・データ受け渡し無害化のところをよく見なおして下さい。
 あとouyou02.txtは上でも書きましたが開いて内容を削除してそのまま保存しておいて下さい。
 準備ができたらブラウザで「localhost」経由でouyou02a.phpにアクセスしてみましょう。もちろんXamppの起動を忘れないで下さいね。動作を確認して、空欄があるとメッセージが出たり、<font size="7">と入力しても文字が拡大されなければOKです。

  

  

  

SPONSORED LINK


2. 確認画面の作りこみ

 準備ができたところで、確認画面ouyou02b.phpを作りこんでいきましょう。上記サンプル画像でも見た通り、現在は、入力されて送られてきたデータを単に表示しているだけです。
 ですがこの確認画面でしなければならないことは、届いたデータを表示する、だけでなく、データを確認してOKなら次の完了画面にデータを送ることと、データを確認してNGなら元の入力画面に戻ることの2つです。
 確認用にデータを表示する方法としては、現在のように単純に表示してもOKですが、「確認画面」や「名前」、あるいは、名前の入力と投稿内容の部分との境がはっきりしないのでちょっとわかりづらい。
 それからこの後、どうやってデータを次のページに送るかを考えると不便です。このように表示されたデータはそのまま送れないので、これとは別に、<input type="hidden">の隠しデータを設定するなどして送る必要があります。データが2重にあるのは非効率でもあります。
 というわけで、データの表示と次ページへの送信の両方を一度にやるために、先の入力ページと同じようにデータ入力部品を使うことにしましょう。つまり、PHPプログラムで<form>タグや<input>タグ、<textarea>タグなどを出力し、データを表示させつつ、次ページに送るためのデータ入力部品とする、ということです。
 では、どんなタグを出力させたらよいでしょうか?確認ページですので、入力ページと同じタグを出力すればいいですよね。同じようにデータを表示できます。というわけで、ouyou02a.phpに設定された<form>タグや<input>タグと同様のものをPHPで出力したいと思います。ouyou02b.phpを次のように編集しましょう。

  ouyou02b.php(php部分以外は省略)
  

 6行目までは変化なし。編集したのはelseに続く{ }内です。echo文を使って<form>タグや<input>タグ、<textarea>タグなどを出力しています。ごちゃごちゃしてややこしいですが、ouyou02a.phpのタグとかなりの部分が同じです。よく見て下さい。
 まず最初(7行目)の<form>タグ。postメソッドでデータを送る設定にしています。送り先のファイル名が「■■■」になっていますが、わかりますよね。このファイルはouyou02b.phpですから、次に来るのは・・・ということです。
 次の行では名前の<input>タグがありますが「value属性」と「readonly属性」が追加されました。value属性はこのテキスト入力欄に設定されるデータが設定されます。前の画面で名前が入力されているはずですので$namaeの値をvalue属性に設定する形で出力しています。「.」(ピリオド)による文字列と変数の連結に注意して見て下さい。
 もう一つreadonly属性ですが、これは<input>タグ、<textarea>タグで使われる属性で「読むだけ」で「更新できない」状態を設定するものです。確認画面なのでここで更新させない、というわけです。
 その次には<textarea>タグがあります。このタグにはvalue属性はなく、<textarea>と</textarea>の間にデータが設定されます。ので、その個所に$messageを出力しています。つまり入力された投稿情報ですね。その上でここでも「readonly属性」を追加して更新できなくしています。
 最後に「OK」ボタンと「戻る」ボタンを設置するタグを出力しています。「OK」ボタンは前の画面ouyou02a.phpでいう「送信」ボタンの表示を変えたもので、この<form>でのデータ送信を実行するボタンになります。「■■■」も前の画面と同じです。
 一方「戻る」ボタンは、前の画面にはありませんでした。前の画面は入力画面なので、同じ位置に「リセット」ボタンがありました。ここで作っているのは確認画面ですので、確認した結果、修正したい場合は、戻って直す、ということになります。戻った時にデータが消えないようにJavascriptの関数を使っています。「■■■」はこの関数です。PHP基本編・展開配慮のところを見て思い出して下さい。
 編集が済んだらブラウザで確認しましょう。ouyou02a.phpからデータを入力して送信すると、確認画面ouyou02b.phpに展開し、入力データがきちんと表示されるか、入力を変更できないかどうか確かめて下さい。確認画面で変更できたらダメですよ。そして戻るボタンで戻った時に入力データが残っているかも見ておきましょう。
 ただ「OK」ボタンは押してもまだ正常動作しません。エラーが出るだけです。というわけで確認画面で「OK」とした次の処理を作っていきます。

  

  


SPONSORED LINK


3. 完了画面の設定

 確認画面で「OK」ボタンが押されると完了画面に展開します。完了画面で必要なことは、データを受け取って、適切に加工処理して、ファイルに保存しすることです。
 単に保存していくだけなら簡単ですが、そうはいきません。掲示板ですから、保存したデータは、読み出して順に並べて表示してやる必要があります。ですので、読み出し処理で便利なようにデータを保存することを考えなくてはいけません。
 保存しなければならないデータは「名前」と「投稿内容」の2つです。掲示板では、次々にこの2つのデータがセットで登録されるわけですので、読み出す際にもこの2つが1セットとなっていいたほうが便利です。
 いろいろな方法がありえますが、ここではこの1セットのデータを1行のデータとして保存することを考えましょう。1行のデータが1セットというのはわかりやすいですし、データを読み出す際に「file()関数」を使えて便利です。

 前の確認画面ouyou02b.phpからはpostメソッドでデータが送られていましたので、それを受け取って整形して、保存することを考えましょう。ということで、サンプルで考えましょう。
 上の準備のところですでにouyou02c.phpは作りましたのでテキストエディタにドラッグ&ドロップして開きましょう。編集はまだですので以下のように入力して下さい。

  ouyou02c.php
  

 HTML部分はOKとしてPHPプログラムの部分。途中のelseまでは問題ないでしょう。ouyou02b.phpと同じです。ここで大事なのはその後です。
 まずコメントにもある通り、上の準備のところで作ったouyou02.txtを開いています。「■■■」が2つもあります!前の方はファイルを開く関数、後ろの方はファイルを開くモードです。
 次に開いたファイルにデータを書き込んでいます。その際、$namaeと「<br>」と$messageと「"¥n"」を連結したものを書き込むようにしています。「■■■」はファイルに書き込む関数です。
 そして最後。開いたファイルを閉じています。ファイルを閉じる関数が「■■■」に入ります。
 プログラムができたら動作させてみましょう。ブラウザから入力画面ouyou02a.phpにアクセスして下さい。ここで次のように入力します。

  

  

 入力したら「送信」。確認画面で「OK」ボタンをクリック。完了画面が正常に表示されましたか?表示されたらデータファイルであるouyou02.txtを開いて見て下さい。開きっぱなしの場合は一旦閉じて開きなおします。データは想定通り1行に保存されていますか?
 1行には保存されていないはずです。そのために「テスト」と3行にわたって入力していただきました。なぜこのように保存されたのでしょうか?それはもちろん「改行」があるからですね。PHPプログラムの記号で表すなら「"¥n"」です。テキストエリアで上記のように入力されたときに送信されるデータは「テスト(改行)テスト(改行)テスト」というデータになり、テキストファイルには入力されたのと同じ形で改行されて保存されます。

  

 でもこれでは1行に1セットのデータとはならず、file()関数でデータを読み出したときには、3つの別々のデータとなってしまいます。それでは困ります。
 これを解決する方法としては、入力された「改行」つまり「"¥n"」を別のものに置き換えてやる、というやり方があります。投稿データを保存したテキストファイル内で改行されることが問題なわけですから、これを改行されないようにすれば良いわけです。では何に置き換えるか?このようなときによく行われるのは「<br>」(改行タグ)に置き換えるという方法です。「<br>」は、HTMLの一部としてブラウザで表示される際には「改行」として機能しますが、テキストファイル内では単なる文字列。改行として機能することはありません。また、保存されたデータを読み出してブラウザで表示する際には「<br>」は改行として機能しますので便利ということもあります。
 というわけで、サンプルの編集はちょっと横に置いておいて文字列の置換の方法を確認しましょう。

SPONSORED LINK


4. 文字列の置換

 ということで、入力データに含まれる改行「"¥n"」をHTMLの改行タグ「<br>」に置き換える方法を確認しましょう。
 文字列の置き換えはいくつかの方法がありますが、ここでは最も基本的な「str_replace()」関数を使う方法を確認します。使い方は以下の通り。

  $hoge = str_replace(キーワード,置換文字,対象文);

 もっと具体的に書くと、以下の通りです。

  

 これを実行すると、最終的に「ゆで麦ゆで米ゆで卵」が出力されます。説明すると、変数$hogeに代入された「なま麦なま米なま卵」に対し、キーワード「なま」にマッチするものを、置換文字「ゆで」に置き換える、という処理です。また、ここではキーワードや置換文字を「なま」「ゆで」と直接設定しましたが、変数に代入して設定することもできます。
 さらに、ここではキーワードを「なま」の1つだけ設定しましたが、複数の文字を一度に設定することもできます。その場合は、配列を使って設定します。配列の設定の仕方を思い出して下さい。array()関数を使うんでしたね。

  

 今度はどうなるでしょうか。変数$hogeの内容「なま麦なま米なま卵」に対し、配列$keywordsに設定されたキーワード「麦」「米」「卵」のいずれかにマッチするものを「ビール!」に置き換えます。ですのでこの処理の結果は「なまビール!なまビール!なまビール!」となります。簡単ですよね。
 というわけで、話を戻しましょう。入力画面で入力されたテキストの改行「"¥n"」を保存する際にHTMLの改行タグ「<br>」に置き換えたい、ということでした。ですので、str_replace()関数にこれらの文字列を設定すればOK、ということになります。
 ですがここで1つ配慮する必要があります。それは「利用者がWindowsとは限らない」ということです。インターネット上に公開されブラウザからアクセスして利用するウェブサービスの場合、多様なユーザー環境を想定しなければなりません。その場合にここで何が問題になるかというと「改行コードの違い」です。これまでテキストの改行といえば「"¥n"」としていましたが、それはこの資料が想定しているWindows環境での話。環境が異なれば改行コードも変わります。
 ですので実は、PHPプログラムで指定するテキストでの改行も「"¥n"」以外に「"¥r"」と「"¥r¥n"」があります。ユーザーの利用環境によって異なってくるわけです。ただ、出力する際は、出力データを表示するエディタやワープロソフトが「¥nは改行の意味」と解釈してくれるので、環境が違っても「¥n」としておけばOK。しかし、入力を受け付ける際はダメです。掲示板からの投稿はどんな環境で入力されるかわかりませんので「改行=¥n」とは限りません。入力データは、何もしなければ、入力された通りに送受信され、入力された通りに保存されてしまいます。ですので、このような複数の改行に対応しておく必要があります。PHPプログラムで「¥nを<br>に置換せよ」とだけ指定していると、利用環境が違って例えば「¥r」という改行コードが入力された場合に想定通りに置換されず問題が起きることになります。
 説明が長くなりましたが、要は、「¥n」と「¥r」と「¥r¥n」の3つの改行のどれが入力されても「<br>」に変換されるように設定しておきましょう、ということです。やり方は上でやりましたね。「なまビール!なまビール!なまビール!」への変換です。念のため、これらの改行記号をPHPで取り扱う際は「"¥n"」の場合と同じく「"」(ダブルコーテーション)で括る必要があります。「"¥r"」や「"¥r¥n"」のように。これも併せて、サンプルの中で確認しましょう。

  ouyou02c.php(php部分以外は省略)
  

 追加したのは真ん中あたり。else{ }の最初のところです。まず3つの改行記号を配列として$kaigyoに設定しています。「■■■」は配列を定義する関数です。
 そしてこの配列$kaigyoを使って、次の行で、掲示板に投稿された内容が格納された変数$messageに含まれる3つの改行をHTMLの改行タグ「<br>」に置き換えています。ここの「■■■」は、文字列の置き換えの関数が入ります。今やったばかりですので大丈夫ですよね。
 ここで注意すべきは「"¥r¥n", "¥r", "¥n"」の指定順です。順不同ではありません。最初に「"¥r¥n"」を持ってきてください。なぜだかわかりますか?
 配列は通常先頭から処理されていきますので、このように指定する場合「"¥r¥n"にマッチしたら置き換え→"¥r"にマッチしたら置き換え→"¥n"にマッチしたら置き換え」と進みます。このとき、もし入力された改行が「"¥r¥n"」の場合、最初のところで「"¥r¥n"」にマッチするので「<br>」に置き換えられて終了となります。ですが「"¥r", "¥n", "¥r¥n"」のような順で指定すると「"¥r"にマッチしたら置き換え→"¥n"にマッチしたら置き換え→"¥r¥n"にマッチしたら置き換え」と処理されますので、もし入力された改行が「"¥r¥n"」の場合、その一部の「"¥r」の部分だけでマッチして「<br>」に置き換えられ、続いて残りの「¥n"」の部分にマッチして「<br>」に置き換えられますので、結果として「"¥r¥n"」は「<br><br>」に置き換えられてしまいます。改行が2つになってしまうわけです。ですので設定順は最初に「"¥r¥n"」を持ってくるようにして下さい。
 編集が済んだら試してみましょう。まずは先ほどのデータが残っていますので「ouyou02.txt」をテキストエディタで開いて内容を削除して上書き保存して閉じましょう。その上でブラウザから「localhost」経由で入力画面ouyou02a.phpにアクセスし、先ほどと同じように「テスト」「テスト」「テスト」と行を分けて(改行して)3行分入力してみて下さい。送信して確認画面。「OK」して完了画面で「投稿ありがとうございました」と表示されたら、もう一度データファイル「ouyou02.txt」を開いて見て下さい。開いたままだった場合は一旦閉じて開きなおします。「名前<br>テスト<br>テスト<br>テスト<br>」といった具合に1行で表示されていれば成功です。改行されて複数行になってたらダメですよ。うまくいったら他の文字列や文章も何度か入力してみて、名前と投稿内容のデータが1行にまとまって追記されていくかどうか試して下さい。

  


SPONSORED LINK


5. データの表示

 ウェブサービスとして提供される電子掲示板といえば、これまでの書き込み、やり取りが時系列的に並ぶのが普通です。ですので、最初の入力画面であるouyou02a.phpに投稿されたデータを読み出して表示する処理を作りましょう。
 ただ、表示のさせ方もいろいろあります。投稿内容を登録された順にするか逆にするか?投稿の入力欄をページの先頭にするか最後にするか?使いやすさを考えて決める必要があります。ここでは、ページの先頭に投稿入力欄を設置し、その下に最新の書き込みから古い書き込みへと順に投稿内容を表示するという方法でいきましょう。簡易掲示板ですので凝った処理は行わない、ということもありますが、掲示板ページを開くとすぐに投稿入力欄があり、入力するとすぐ下に表示されるというのはわかりやすい、ということもあります。
 ここで便利な関数を確認しましょう。投稿内容が下からどんどん追加されていくデータファイルがあって、それを読み出して配列に格納して使う、という場合、一番古いものを先頭に新しいものへ順に並べる場合はそのまま表示すればOKですが、最新の登録内容から古いものへと順に並べたい場合、データの登録順とは逆にして表示する必要があります。
 この場合の方法としては、count()関数で配列の要素数を取得し、その数から最後の要素のインデックスキーを求め、forループでカウントダウンして0番まで処理していく、というものがあります。つまり、投稿データの件数が10件の場合、それを配列に取り込んでその要素数「10」をcount()関数で求め、これによって配列の最後のキーが「10-1」つまり「9」と計算できますので、forループでカウントダウンして、配列[9]→配列[8]→配列[7]→・・→配列[1]→配列[0]、と表示していけば、データの登録順とは逆に表示することができます。
 しかし。面倒くさい。
 というわけで、配列の要素の順序をそっくり逆順にする関数を使います。array_reverse()関数です。リバースです。PHP基本編・配列の資料で、配列の関数はいろいろあると書きましたが、いろいろある関数の1つ。使い方は以下の通りです。

  $配列 = array_reverse ($配列);

 これだけです。array_reverse()関数は、設定された配列を逆順にします。この書き方例は、その上で配列に代入しています。設定される配列と代入される配列は同じでも違ってもかまいません。同じなら配列が逆順に再設定される、ということになります。
 というわけで、ouyou02a.phpに表示処理を作り込んでいきたいと思います。このファイルは拡張子こそ「~.php」ですが、今のところ<form>タグなどHTMLしか書かれていませんでした。サンプルを見て考えていきましょう。

  ouyou02a.php(php部分以外は省略)
  

 こんなに短いプログラムなのに3か所も「■■■」があります。コメントをヒントに何が入るか考えていきましょう。
 まずは2行目。「ファイルを配列に読み込み」とコメントにある通り、データファイル「ouyou02.txt」を読み込んでいます。配列に読み込むということですので、「■■■」には、PHP基本編・ファイル入出力でやったそのままズバリな名前の関数が入ります。これまで同様「■■■」は3文字とは限りませんよ。ファイルを読み込み1行ずつに分けて配列に取り込んでいきます。
 次の行。「配列を逆順に」というコメントがありますが、これは今やったばかり。すぐわかるでしょう。これによって配列に取り込まれたデータが逆順になります。
 そしてその次で、foreachループで、配列$datalistの全要素を処理しています。ここの「■■■」は何でしたっけ?思い出して下さい。
 また表示内容は、「<hr>」タグで投稿ごとに罫線を引いて区切っています。それに続けて$valueに格納された投稿データを表示しています。最後のデータまで繰り返し処理されます。
 編集が済んだら「localhost」経由で表示してみましょう。ouyou02a.phpにアクセスしてデータを送信するとouyou02b.phpの確認画面に展開。確認「OK」とすると完了画面ouyou02c.php。「掲示板に戻る」でouyou02a.phpが表示されて投稿内容が追加されていればOK。何度か入力してみてどんどん追加されていけば簡易掲示板の出来上がり!となります。

  


SPONSORED LINK


練習問題

 このページで用いたファイルを使い以下の課題に取り組みましょう。
  1. 掲示板が見やすくなるよう、①名前の前に「名前:」、②名前を青色で下線、を表示されるようにしなさい。
  2. 名前の後に「/12/20 14:18:32」という形式で投稿日時を保存し表示されるようにしなさい。
練習問題の出力例

ページのトップへ戻る
SPONSORED LINK