日記帳スペシャル

 既にKOMONETの方では公開・配布しているんですが、最近機能追加、及び修正を重ね、まあまあの代物になりましたので、ここら辺でソースの解説をしておこうかと思います。

[新機能] 従来の日記帳に画像アップ機能を新たに追加しました。また、記事修正時に画像もアップし直せるようにしています。もちろん、記事削除の際にはその画像も一緒に削除できます。尚、URLに自動的にリンクが付く機能に、記事修正時一部不具合がありましたので、コードを修正しています。

*注意…このスクリプトはPHP4.2.0以降のスーパーグローバル変数に対応したものになっています。

<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=x-sjis">
<TITLE>KOMOダイアリー</TITLE>

<STYLE TYPE="text/css">
<!--
:link {
Color : blue ;
Text-Decoration : None
}
:active {
Color : blue ;
Text-Decoration : None
}
:visited {
Color : blue ;
Text-Decoration : None
}
A:hover {
Color : blue ;
Text-Decoration : Underline
}
-->
</STYLE>

</HEAD>
<BODY BGCOLOR="#FFCCFF">
<CENTER>
<P><IMG SRC="title.gif" WIDTH="415" HEIGHT="82" ALIGN="BOTTOM" BORDER="0"></P>
<P><FONT COLOR="#990066"><B>編集機能付きの日記帳スクリプトだよ!結構便利なので、使って見てね(^o^)丿</B></FONT><BR>
パスワードは「777」に設定しています。お試しあれ!(^o^)丿</P>
通常のHTMLによるページの先頭部分です。解説は要りませんね(^^ゞ
<?php
//============================初期設定==============================
$data_file = './diary.dat'; //データログ用ファイル
$passwd = '777'; //管理者用パスワード
$data_max = 100; //データ最大記録数
$page_view = 10; //1ページの記事表示件数
$back_img = ''; //バック用画像
$now = date("Y/m/d(D)"); //時間の取得
$up_dir = '/img/';
$path = dirname($_SERVER["PATH_TRANSLATED"]).$up_dir;
$w_max = 200; //画像の横幅の最大値(ピクセル)
$h_max = 200; //画像の縦幅の最大値(ピクセル)
$w_limit = 600; //画像の横幅の制限値(ピクセル)
$h_limit = 400; //画像の縦幅の制限値(ピクセル)
$err_msg = "画像のサイズが大きすぎます。画像をアップロードし直して下さい。";
$PHP_SELF = './komodiary.php';
初期設定部分です。

スーパーグローバル変数で$PHP_SELFの取得に失敗してしまった為、ここで変数$PHP_SELFの値を決定しています。
//===============インライン関数===================
function inline_link($link){
 $link = ereg_replace("(https?|ftp|news)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)","<a href=\"\\1\\2\" target=\"_blank\">\\1\\2</a>",$link);
 return $link;
}
コメント中にURLらしき記述があると、自動的にリンクを貼る関数です。もうお決まりですね(^.^)
if($_POST['action'] == "regist"){
 //フォームデータの取得
 $code = $_POST['code'];
 $subject = $_POST['subject'];
 $msg = $_POST['msg'];
 $fname = $_POST['fname'];
 $date = $_POST['date'];
 $button = $_POST['button'];
 $upfile = $_FILES['upfile']['tmp_name'];
 $upfile_name = $_FILES['upfile']['name'];
アクションが「regist」の場合の処理の始まりです。

まずフォームデータを取得します。
 //処理の分岐
 if($button == "修正/更新"){
  //ここから書き込みデータの調整
  $subject = htmlspecialchars($subject);
  $msg = htmlspecialchars($msg);
  $msg = nl2br($msg);
  $msg = str_replace("\r", "", $msg);
  $msg = str_replace("\n", "", $msg);
  //ログファイルの区切文字(",")と区別するために文字コード(&#44)に書き換える。
  $subject = str_replace(",", "&#44;",$subject);
  $msg = str_replace(",", "&#44;",$msg);
  //インラインリンクを実現(URLのみ)
  $msg = inline_link($msg);
「修正/更新」ボタンを押した場合の処理の始まりです。

書き込みデータの調整をします。タグの無効化、改行記号の変換、コンマ文字の置き換え、インラインリンクの実現など。
  if($upfile){
   $source = $upfile;
   $source_name = $upfile_name;
   $source_name = ereg_replace("^(.:.*\\\\)?(.*)", "\\2", $source_name);
   if(($source != "none")&&($source != "")){
    $dest = $path.$source_name;
    $imagesize = getimagesize($source);
    if(($imagesize[0] > $w_limit) || ($imagesize[1] > $h_limit)){
     $err_flag = 1;
     echo "<META HTTP-EQUIV=refresh content=0;URL=$PHP_SELF?err_flag=$err_flag>";
     exit;
    }
    if(copy($source,$dest)){
     $imagesize = getimagesize($dest);
     switch($imagesize[2]){
      case 0:
      unlink($dest);
      break;
      case 1:
      $out = $code.".gif";
      rename($dest,$path.$out);
      break;
      case 2:
      $out = $code.".jpg";
      rename($dest,$path.$out);
      break;
      case 3:
      $out = $code.".png";
      rename($dest,$path.$out);
      break;
     }
     $fname = $out;
    }
   }
  }
修正用のアップ画像がある場合の処理です。

初期設定部分で、アップできる画像の縦横サイズを限定していますので、もし限定サイズを超えた画像をアップしようとした時は、エラーフラグを立てて再読み込みし、exitで残りの処理を抜けます。変数
$imagesize[0]の値は画像の幅を、$imagesize[1]は高さを表します。

アップしようとしている画像のサイズが限定サイズ内であれば、通常の画像コピー処理をし、保存した画像ファイル名を取得します。ここでは、画像の種類を
GIFJPGPNGの3つに限定しています。
  $repdata = file($data_file);
  $fp = fopen($data_file, "w");
  for($i=0; $i<count($repdata); $i++){
   list($rcode,$rsubject,$rmsg,$rfname,$rdate) = split( ",", $repdata[$i]);
   if ($code == $rcode) {
    $repdata[$i] = "$code,$subject,$msg,$fname,$date\n";
    fputs($fp, $repdata[$i]);
   } else {
    fputs($fp, $repdata[$i]);
   }
  }
  fclose($fp);
  echo "<META HTTP-EQUIV=refresh content=0;URL=$PHP_SELF>";
  exit;
ログファイルを開いて、投稿記事の内容を修正入力します。ここは従来の「日記帳」と同じ処理です。

画像表示をリフレッシュするため、再読み込みしています。
 }elseif($button == "削除"){
  $deldata = file($data_file);
  $fp = fopen($data_file, "w");
  for($i=0; $i<count($deldata); $i++){
   list($dcode,$dsubject,$dmsg,$dfname,$ddate) = split(",", $deldata[$i]);
   if ($code == $dcode) {
    $deldata[$i] = "";
    if($dfname){
     unlink(".".$up_dir.$dfname);
    }
   }
   fputs($fp, $deldata[$i]);
  }
  fclose($fp);
「削除」ボタンを押した場合の処理です。

記事内容だけでなく、画像ファイルも一緒に
unlink()関数で削除しています。

★int unlink ( string filename )関数・・・引数filename で指定されたファイルを削除します。成功すると0を返し、エラーの場合はfalseを返します。
 }else{
  if($msg){
   $code = time(); //アクセス時の秒数
   //ここから書き込みデータの調整
   $subject = htmlspecialchars($subject);
   $subject = nl2br($subject);
   $subject = str_replace("\r", "", $subject);
   $subject = str_replace("\n", "", $subject);
   $msg = htmlspecialchars($msg);
   $msg = nl2br($msg);
   $msg = str_replace("\r", "", $msg);
   $msg = str_replace("\n", "", $msg);
   //ログファイルの区切文字(",")と区別するために文字コード(&#44)に書き換える。
   $subject = str_replace(",", "&#44;",$subject);
   $msg = str_replace(",", "&#44;",$msg);
   //インラインリンクを実現(URLのみ)
   $msg = inline_link($msg);
通常の記事投稿の場合の処理の始まりです。

記事wpの変数$codeは、アクセス時の秒数から取得しています。

他の処理内容は既に出て来ていますね。
   if($upfile){
    $source = $upfile;
    $source_name = $upfile_name;
    $source_name = ereg_replace("^(.:.*\\\\)?(.*)", "\\2", $source_name);
    if(($source != "none")&&($source != "")){
     $dest = $path.$source_name;
     $imagesize = getimagesize($source);
     if(($imagesize[0] > $w_limit) || ($imagesize[1] > $h_limit)){
      $err_flag = 1;
     }else{
      if(copy($source,$dest)){
       $imagesize = getimagesize($dest);
       switch($imagesize[2]){
        case 0:
        unlink($dest);
        break;
        case 1:
        $out = $code.".gif";
        rename($dest,$path.$out);
        break;
        case 2:
        $out = $code.".jpg";
        rename($dest,$path.$out);
        break;
        case 3:
        $out = $code.".png";
        rename($dest,$path.$out);
        break;
       }
      }
     }
    }
    $fname = $out;
   }
アップ画像がある場合の処理です。

この部分の処理内容は既に出て来ていますね(^.^)修正時の場合と違うのは、アップしようとしている画像の縦横サイズが限定値を超えている場合、エラーフラグを立てて画像のアップのみを中止する点です。書き込み記事はサーバにアップします。(この後の処理)
   //ログファイルの区切文字(",")と区別するために文字コード(&#44)に書き換える。
   $fname = str_replace(",", "&#44;",$fname);
   //配列要素を文字列により連結
   $input_msg = implode(",", array($code,$subject,$msg,$fname,$date));
   $message = file($data_file);
   $fp = fopen($data_file, "w");
   rewind($fp);
   fputs($fp, "$input_msg\n");
   //最大記録数の調整
   if($data_max <= count($message)){
    $msg_num = $data_max - 1;
   }else{
    $msg_num = count($message);
   }
   for($i = 0; $i < $msg_num; $i++){
    fputs($fp, $message[$i]);
   }
   fclose($fp);
   unset($message);
  }
 }
新規書き込みの時の処理部分です。

ここは掲示板なんかでもうお馴染みですね。
}elseif(($_POST['action'] == "edit") && ($_POST['password'] == $passwd)){
 $kanri_flag = 1;
 //フォームデータの取得
 $e_code = $_POST['e_code'];
管理用画面での処理内容の始まりです。パスワードが合致すると、管理フラグを立てています。これはページ最下部の管理窓表示の可否に使っています。
 if($e_code < 1) {
  echo "<form action=$PHP_SELF method=POST ENCTYPE=multipart/form-data>\n";
  echo "<input type=hidden name=action value=regist>\n";
  echo "<table border=0>\n";
  echo "<tr><td align=right>日付:</td><td><input type=text size=20 name=date value=$now></td></tr>\n";
  echo "<tr><td align=right>題名:</td><td><input type=text size=35 name=subject></td></tr>\n";
  echo "<tr><td align=right>コメント:</td><td><textarea name=msg rows=6 cols=50></textarea></td></tr>\n";
  echo "<tr><td align=right>添付画像:</td><td><INPUT TYPE=file NAME=upfile SIZE=35></td></tr>\n";
  echo "</table>\n";
  echo "<input type=submit name=button value=送信/更新> <input type=reset value=リセット>\n";
管理画面での新規投稿の場合の入力フォームを表示します。
 }else{
  $comdata = file($data_file);
  for($i=0; $i<count($comdata); $i++){
   list($ccode,$csubject,$cmsg,$cfname,$cdate) = split(",", $comdata[$i]);
   if ($e_code == $ccode) {
    $e_subject = $csubject;
    $e_msg = str_replace("<br />", "\n", $cmsg);
    $e_msg = strip_tags($e_msg);
    $e_date = $cdate;
    $e_fname = $cfname;
    break;
   }
  }
  unset($comdata);
管理画面で書き込み記事の修正をかけた時の処理の始まりです。

修正をかけた記事の内容をログファイルからそれぞれ抜き出します。本文中に自動的に付いたリンク用タグは、
strip_tags()関数を使って削除しています。改行タグを先に「\n」に変換している所がミソです。

★string strip_tags ( string str [ , string allowable_tags ] )関数・・・引数str で指定した文字列から、すべてのHTMLおよびPHPタグを取り除きます。不完全あるいは間違ったタグの場合は、エラーとなり警告を発生します。オプションの2番目の引数により、取り除かないタグを指定できます。
  echo "<form action=$PHP_SELF method=POST ENCTYPE=multipart/form-data>\n";
  echo "<input type=hidden name=action value=regist>\n";
  echo "<input type=hidden name=code value=\"$e_code\">\n";
  echo "<input type=hidden name=fname value=\"$e_fname\">\n";
  echo "<table border=0>\n";
  echo "<tr><td align=right>日付:</td><td><input type=text size=20 name=date value=\"$e_date\"></td></tr>\n";
  echo "<tr><td align=right>題名:</td><td><input type=text size=35 name=subject value=\"$e_subject\"></td></tr>\n";
  echo "<tr><td align=right>コメント:</td><td><textarea name=msg rows=6 cols=50>$e_msg</textarea></td></tr>\n";
  echo "<tr><td align=right>添付画像:</td><td><INPUT TYPE=file NAME=upfile SIZE=35></td></tr>\n";
  echo "</table>\n";
  echo "<input type=submit name=button value=修正/更新> <input type=submit name=button value=削除>\n";
 }
 echo "</form>\n";
}
上で受け取った修正記事の内容を、入力フォームのそれぞれの値に読み込みます。
//エラー処理
if($err_flag || $_GET['err_flag']){
 echo $err_msg;
 echo "<BR><BR><A HREF=$PHP_SELF onMouseOver=this.style.color='red' onMouseOut=this.style.color='blue'><やり直す></A>\n";
 exit;
}
エラー処理部分です。

ここまでの処理でエラーを吐いた場合、これ以降の処理をexitで抜けます。
$message = file($data_file);
$msg_count = count($message);
if($_POST['pline'] == ""){
 $p_line = 0;
}else{
 $p_line = $_POST['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($vcode,$vsubject,$vmsg,$vfname,$vdate) = split( ",", $message[$i]);
 echo "<form action=$PHP_SELF method=POST>\n";
 echo "<input type=hidden name=action value=edit>\n";
 echo "<input type=hidden name=e_code value=$vcode>\n";
 echo "<table border=1 width=600 bordercolor=#FF00CC>\n";
 echo "<tr><td><b>■ $vdate</b>\n";
 echo " <font color='blue' size=4><b>$vsubject</b></font>\n";
 if (($_POST['action'] == "edit") && ($_POST['password'] == $passwd)) {
  echo "<input type=hidden name=password value=$passwd> <input type=submit value=訂正>\n";
 }
 echo "</td></tr><tr><td><blockquote>\n";
 if($vfname && file_exists("$path$vfname")){
  $size = getimagesize("$path$vfname");
  $img_w=$size[0];
  $img_h=$size[1];
  if($img_w > $w_max || $img_h > $h_max){
   $w_ritu = $w_max / $img_w;
   $h_ritu = $h_max / $img_h;
   ($w_ritu < $h_ritu) ? $key = $w_ritu : $key = $h_ritu;
   $width = (int) $img_w * $key;
   $height = (int) $img_h * $key;
   echo "<A HREF=.$up_dir$vfname TARGET=_blank><img src=.$up_dir$vfname WIDTH=" . $width . " HEIGHT=" . $height . " ALIGN=LEFT></A><br><br>";
  }else{
   echo "<img src=.$up_dir$vfname ALIGN=LEFT><br><br>";
  }
 }
 echo "$vmsg</blockquote></td></tr></table></form>\n";
}
?>
ログファイルの記事を読み込み、一覧表示します。

この部分は掲示板などでお馴染みですね(^.^)投稿画像がある場合は、本文の前に表示します。表示サイズの制限を設けていますので、縦横の制限値を超えた場合は、自動でリサイズされて表示されます。縮小表示した場合は、元サイズの画像にリンクを貼ります。

従来は画像の下に本文が入っていましたが、画像に「左」属性を付けることによって、本文を画像の右側に表示するよう訂正しました。
<P>
<TABLE BORDER="0" WIDTH="600">
 <TR>
  <TD WIDTH="50%">

<?php
if($page_end >= $page_view){
 $page_count = floor($page_end / $page_view);
 $prev_line = ($page_count - 1) * $page_view;
 print "<form method=Post action=$PHP_SELF>\n";
 if (($_POST['action'] == 'edit') && ($_POST['password'] == $passwd)){
  echo "<input type=hidden name=action value=edit>\n";
  echo "<input type=hidden name=password value=$passwd>\n";
 }
 print "<input type=hidden name=pline value=$prev_line>\n";
 print "<input type=submit value=前のページ>\n";
 print "</form>\n";
}else{
 print "&nbsp;\n";
}
?>

  </TD>
  <TD WIDTH="50%"><P ALIGN="RIGHT">

<?php
$next_line = $page_end + 1;
if($page_end != $end_data){
 print "<form method=Post action=$PHP_SELF>\n";
 if (($_POST['action'] == 'edit') && ($_POST['password'] == $passwd)){
  echo "<input type=hidden name=action value=edit>\n";
  echo "<input type=hidden name=password value=$passwd>\n";
 }
 print "<input type=hidden name=pline value=$next_line>\n";
 print "<input type=submit value=次のページ>\n";
 print "</form>\n";
}else{
 print "&nbsp;\n";
}
?>

  </TD>
 </TR>
</TABLE>
ここは、ページ移動の為のボタンを表示する処理部分です。

1ページ当りに表示する記事数を設定していますので、このボタンでページ間を移動します。
<?php
if($kanri_flag < 1){
 echo "<div align=left>\n";
 echo "<form action=$PHP_SELF method=POST>\n";
 echo "<input type=hidden name=action value=edit>\n";
 echo "<input type=password size=10 name=password>\n";
 echo " <input type=submit value=管理><br>\n";
 echo "</form></div>\n";
}
?>
管理用ページに入る為の、管理窓を表示する部分です。

上で立てた管理フラグの値を使って、管理窓の表示の可否を決定しています。
</BODY>
</HTML>
HTMLの終了部分です。

 *上の内容をこのまま複写しても動きません。何故なら、表示を見やすくする為コード中に全角スペースが入っているからです。実際にお使いになる時は、この点を修正してからサーバにアップして下さい。

HOME