画像掲示板Light
前々からずーっと作りたいなーと思っていたんですが、なかなかその手法が分からず困っていました。ここに来てようやくやり方が分かり、ソースを公開致します。基本は従来の掲示板ですので、手を加えた部分だけ解説させて頂きます。又、今回のはアップする画像に関して何ら制限(ファイルの大きさとかサイズ)を加えていないライト版です。ご了承下さい。
スクリプト本体以外に必要なものは、ログ保存用ファイル「g_bbs.log」と画像保存用のimgフォルダです。imgフォルダは画像の書き込みができなくては行けないので、パーミッションを「7*7」にして下さい。あっ、それと、ホームページへリンクする為の小さい画像も必要です。
<HTML> <HEAD> <TITLE>画像掲示板Light</TITLE> </HEAD> <BODY BGCOLOR="#ffffee" LINK="red" VLINK="red"> <FORM ACTION="<?php echo $PHP_SELF; ?>" METHOD="POST" ENCTYPE="multipart/form-data"> <P><INPUT TYPE="HIDDEN" NAME="action" SIZE="-1" VALUE="regist"></P> <P ALIGN="CENTER"><FONT SIZE="6" COLOR="#000099">画像掲示板Light</FONT></P> <P ALIGN="CENTER"><FONT SIZE="2" COLOR="red">お名前とコメントは必ず書き込んで下さい。エラーになります。(何も反応しないよ!)記事の最大記録数は100件です。</FONT></P> <BLOCKQUOTE> <P> <TABLE BORDER="0" WIDTH="88%"> <TR> <TD WIDTH="12%" ALIGN="RIGHT"> <P ALIGN="RIGHT">お名前: </TD> <TD WIDTH="21%"><INPUT TYPE="TEXT" NAME="name" SIZE="15"> </TD> <TD WIDTH="10%"> <P ALIGN="RIGHT">E-mail: </TD> <TD WIDTH="57%"><INPUT TYPE="TEXT" NAME="email" SIZE="25"></TD> </TR> <TR> <TD WIDTH="12%" ALIGN="RIGHT"> <P ALIGN="RIGHT">HomePage: </TD> <TD COLSPAN="3"><INPUT TYPE="TEXT" NAME="hp" SIZE="40"></TD> </TR> <TR> <TD WIDTH="12%" ALIGN="RIGHT"> <P ALIGN="RIGHT">題目: </TD> <TD COLSPAN="3"><INPUT TYPE="TEXT" NAME="subject" SIZE="40"> 題目色:<INPUT TYPE="RADIO" NAME="scolor" VALUE="blue" checked><B><FONT COLOR="blue">青</FONT></B> <INPUT TYPE="RADIO" NAME="scolor" VALUE="red"><B><FONT COLOR="red">赤</FONT></B> <INPUT TYPE="RADIO" NAME="scolor" VALUE="green"><B><FONT COLOR="green">緑</FONT></B> <INPUT TYPE="RADIO" NAME="scolor" VALUE="#996600"><B><FONT COLOR="#996600">茶</FONT></B> <INPUT TYPE="RADIO" NAME="scolor" VALUE="#660099"><B><FONT COLOR="#660099">紫</FONT></B></TD> </TR> <TR> <TD WIDTH="12%" ALIGN="RIGHT"> <P ALIGN="RIGHT">コメント: </TD> <TD COLSPAN="3"><TEXTAREA NAME="comment" ROWS="4" COLS="60"></TEXTAREA></TD> </TR> |
通常の記事書き込み部分なので、従来の掲示板とほとんど同じです。ただ、今回はファイルをアップしてやらなくては行けないので、ENCTYPEにmultipart/form-dataを指定します。 |
<TR> <TD WIDTH="12%" ALIGN="RIGHT"> <P ALIGN="RIGHT">添付画像: </TD> <TD COLSPAN="3"><INPUT TYPE="file" NAME="upfile" SIZE="35"><FONT SIZE="2" COLOR="#CC0000"> *GIF、JPG、PNG画像のみ有効。H画像はもちろん禁止!</FONT></TD> </TR> |
ファイルアップロード用の項目を追加します。左の赤色の部分でTYPEをfileに指定してやるだけで、テキストボックスの右側に「参照...」ボタンが現れます。 |
<TR> <TD WIDTH="12%"> <P ALIGN="RIGHT">削除キー: </TD> <TD COLSPAN="3"><INPUT TYPE="PASSWORD" NAME="pass" SIZE="7"><FONT SIZE="2" COLOR="#CC0000"> *半角英数4文字以上推奨。削除キーを設定すると、いつでもご自分の記事を削除できます。</FONT></TD> </TR> <TR> <TD WIDTH="12%"> </TD> <TD COLSPAN="3"> <?php if ($flags == 'return') { print "<input type=submit value=[" . $return . "]に返信>\n"; print "<input type=hidden name=ress value=$code>\n"; } else { print "<INPUT TYPE=SUBMIT VALUE=書き込み/更新> <INPUT TYPE=RESET VALUE=リセット>\n"; } ?></TD> </TR></TABLE> </FORM> |
この部分は従来と全く同じです。 |
//===================初期設定===================== //時間の取得 $now = date("Y/m/d H:i:s"); $data_file = "./g_bbs.log"; //データファイル名 $data_max = 100; //データ最大記録数 $page_view = 10; //1ページの記事表示件数 $homegif = "./home.gif"; //ホームページへのリンク用画像 $passwd = "1234"; //管理者用パスワード $up_dir = '/img/'; $path = dirname($PATH_TRANSLATED).$up_dir; |
このファイルと同じ場所に、画像アップ用のimgフォルダを作ります。又、位置関係を取得する為のパス指定は、必ずスクリプトの最初で設定して下さい。途中で設定した場合、エラーになる可能性があります。 |
//===============データの削除================== if ($action == "delete") { if(($delcode != "") && ($password != "")){ $delfile = file($data_file); $fp = fopen($data_file, "w"); for($i=0; $i<sizeof($delfile); $i++){ list($dcode,$dress,$dname,$demail,$dhp,$dsubject,$dscolor,$dcomment,$dfname,$dpass,$dnow,$dhost,$dagent) = split( ",", $delfile[$i]); if (($password == $dpass) || ($password == $passwd)) { if ($delcode != $dcode) { fputs($fp,$delfile[$i]); } } else { fputs($fp,$delfile[$i]); } } fclose($fp); } } |
ほとんど従来と同じですが、アップしたファイルを呼び出す際のファイル名を変数に追加しなくては行けません。 |
//===============インライン関数=================== function inline_link($link){ $link = ereg_replace("(https?|ftp|news)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)","<a href=\"\\1\\2\" target=\"_blank\">\\1\\2</a>",$link); return $link; } |
従来と同じ。 |
//===============データの書き込み================= if ($action == "regist") { if (($name != "") && ($comment != "")) { //ホスト名を取得 $host = getenv("REMOTE_HOST"); $addr = getenv("REMOTE_ADDR"); if($host == "" || $host ==$addr){ $host = gethostbyaddr($addr); } //訪問者のブラウザ名を取得 $agent = getenv("HTTP_USER_AGENT"); //ここから書き込みデータの調整 $name = htmlspecialchars($name); //特殊文字のHTMLエントリへの変換 $name = str_replace("\r", "", $name); //文字列の置換 $name = str_replace("\n", "", $name); $email = htmlspecialchars($email); $email = str_replace("\r", "", $email); $email = str_replace("\n", "", $email); $hp = htmlspecialchars($hp); $hp = str_replace("\r", "", $hp); $hp = str_replace("\n", "", $hp); $subject = htmlspecialchars($subject); $subject = str_replace("\r", "", $subject); $subject = str_replace("\n", "", $subject); $comment = htmlspecialchars($comment); $comment = nl2br($comment); //HTML改行文字の挿入 $comment = str_replace("\r", "", $comment); $comment = str_replace("\n", "", $comment); //ログファイルの区切文字(",")と区別するために文字コード(,)に書き換える。 $ress = str_replace(",", ",",$ress); $name = str_replace(",", ",",$name); $email = str_replace(",", ",",$email); $hp = str_replace(",", ",",$hp); $subject = str_replace(",", ",",$subject); $comment = str_replace(",", ",",$comment); //インラインリンクを実現(URLのみ) $comment = inline_link($comment); //記事番号をゲット $message = file($data_file); if(sizeof($message) < 1){ $new_code = 1; } else { list($ncode,$nress,$nname,$nemail,$nhp,$nsubject,$nscolor,$ncomment,$nfname,$npass,$nnow,$nhost,$nagent) = split( ",", $message[0]); $new_code = $ncode + 1; } |
ここもほとんど従来と同じですが、アップしたファイルを呼び出す際のファイル名を変数に追加しなくては行けません。 |
if($upfile){ $source = $upfile; $source_name = $upfile_name; $source_name = ereg_replace("^(.:.*\\\\)?(.*)", "\\2", $source_name); if(($source != "none")&&($source != "")){ $dest = $path.$source_name; if(copy($source,$dest)){ $imagesize = getimagesize($dest); switch($imagesize[2]){ case 0: unlink($dest); break; case 1: $out = $new_code.".gif"; rename($dest,$path.$out); break; case 2: $out = $new_code.".jpg"; rename($dest,$path.$out); break; case 3: $out = $new_code.".png"; rename($dest,$path.$out); break; } } } } $fname = $out; //ログファイルの区切文字(",")と区別するために文字コード(,)に書き換える。 $fname = str_replace(",", ",",$fname); ←修正追加しました。 |
ここが新たに追加した画像アップ処理の心臓部です。 最初の部分は、フォームから送られて来た変数$upfileと$upfile_nameを元に、必要な情報をゲットし加工しています。 次に/tmpディレクトリに一旦アップされたソースファイル$sourceを、画像格納用に作った/imgディレクトリの中にコピーします。 そして、getimagesize関数で得た情報を元に、画像の種類を洗い出し、それぞれに記事番号と同じ名前を付けます。 |
//配列要素を文字列により連結 $input_msg = implode(",", array($new_code,$ress,$name,$email,$hp,$subject,$scolor,$comment,$fname,$pass,$now,$host,$agent)); $fp = fopen($data_file, "w"); rewind($fp); fputs($fp, "$input_msg\n"); //最大記録数の調整 if($data_max <= sizeof($message)) $msg_num = $data_max - 1; else $msg_num = sizeof($message); for($i = 0; $i < $msg_num; $i++){ fputs($fp, $message[$i]); } fclose($fp); unset($message); } } |
ここもほとんど従来と同じですが、アップしたファイルを呼び出す際のファイル名を変数に追加しなくては行けません。 ここで追加した変数$fnameには、上の処理で得た「記事番号+画像拡張子」情報が格納されます。 |
//親記事だけを抜き出す $message = file($data_file); for($i=0; $i<sizeof($message); $i++){ list($rcode,$rress,$rname,$remail,$rhp,$rsubject,$rscolor,$rcomment,$rfname,$rpass,$rnow,$rhost,$ragent) = split( ",", $message[$i]); if($rress == ""){ $PARENT[] = $message[$i]; } } |
ここもほとんど従来と同じですが、アップしたファイルを呼び出す際のファイル名を変数に追加しなくては行けません。 |
//==================HTML表示====================== //1ページ当たりの表示件数の調整 $msg_count = count($PARENT); if($pline == "") $p_line = 0; else $p_line = $pline; $end_data = $msg_count - 1; $page_end = $p_line + ($page_view - 1); if($page_end >= $end_data) $page_end = $end_data; |
従来と同じ。 |
for($i=$p_line; $i<=$page_end; $i++){ list($code2,$ress2,$name2,$email2,$hp2,$subject2,$scolor2,$comment2,$fname2,$pass2,$now2,$host2,$agent2) = split(",", $PARENT[$i]); |
ここもほとんど従来と同じですが、アップしたファイルを呼び出す際のファイル名を変数に追加しなくては行けません。 |
//親記事の表示 print "<form method=POST action=$PHP_SELF>\n"; print "<input type=radio name=delcode value=$code2>\n"; print "<font size=4 color=$scolor2><b>$subject2</b></font>\n"; if($email2 != "") print " <a href=mailto:$email2><b>$name2</b></a>\n"; else print " <b>$name2</b>\n"; if($hp2 != ""){ print " <a href=$hp2 target=_top><img src=$homegif border=0></a>\n"; } print " <font size=2 color='green'>$now2</font>\n"; print "<input type=hidden name=action value=delete>\n"; print "<font size=2>パスワード:</font><input type=password size=7 name=password>\n"; print "<input type=submit value=削除></form>\n"; if($fname2 && file_exists("$path$fname2")){ print "<img src=.$up_dir$fname2><br><br>\n"; } print "$comment2<br><br>\n"; print "<form method=POST action=$PHP_SELF>\n"; print "<input type=submit value=返信>\n"; print "<input type=hidden name=code value=" . $code2 . ">\n"; print "<input type=hidden name=return value=" . $subject2 . ">\n"; print "<input type=hidden name=flags value=return>\n"; print "<font size=2>[$host2] $agent2</font>\n"; print "</form></blockquote>\n"; |
アップされた画像をコメントの前に呼び出しています。ここで注意が必要なのは、SRCでの指定方法です。 「.$up_dir$fname2」の最初にコンマが入っている事にお気づきですか?これは相対パスで同じ場所を示す時のコンマですから、忘れずに付けておいて下さい。このコンマがないとエラーになります。 |
//返信記事の表示 for($j=0; $j<sizeof($message); $j++){ list($code3,$ress3,$name3,$email3,$hp3,$subject3,$scolor3,$comment3,$fname3,$pass3,$now3,$host3,$agent3) = split(",", $message[$j]); if ($code2 == $ress3) { print "<blockquote>\n"; print "<form method=POST action=$PHP_SELF>\n"; print "<input type=radio name=delcode value=$code3>\n"; print "RE:<font color=$scolor3><b>$subject3</b></font>\n"; if ($email3 != "") { print " <a href=mailto:$email3><strong>$name3</strong></a>\n"; } else { print " <strong>$name3</strong>\n"; } if($hp3 != ""){ print " <a href=$hp3 target=_top><img src=$homegif border=0></a>\n"; } print " <font size=2 color='green'>$now3</font>\n"; print "<input type=hidden name=action value=delete>\n"; print "<font size=2>パスワード:</font><input type=password size=7 name=password>\n"; print "<input type=submit value=削除><blockquote>\n"; if($fname3 && file_exists("$path$fname3")){ print "<img src=.$up_dir$fname3><br><br>\n"; } print "$comment3<br><br>\n"; print "<font size=2>[$host3] $agent3</font></blockquote>\n"; print "</form></blockquote>\n"; } } print "<hr>\n"; } |
ここもほとんど従来と同じですが、アップしたファイルを呼び出す際のファイル名を変数に追加しなくては行けません。 又、親記事同様、アップされた画像をコメントの前に呼び出すようにしています。 |
unset($message); $next_line = $page_end + 1; if($page_end != $end_data){ print "<form method=Post action=$PHP_SELF>\n"; print "<input type=hidden name=pline value=$next_line>\n"; print "<input type=submit value=次のページ>\n"; print "</form>\n"; } ?> </BLOCKQUOTE> </BODY> </HTML> |
従来と同じ。 |
*上の内容をこのまま複写しても動きません。何故なら、表示を見やすくする為コード中に全角スペースが入っているからです。実際にお使いになる時は、この点を修正してからサーバにアップして下さい。