投票コメント機能製作メモ27

  最近2ちゃんねるの仕様を書いたサイトを読んでいたら、トリップに付いて書かれていました。改めてコメント機能のトリップ用関数を見直したら、ごく一部まずい箇所が見つかったので修正を入れました。
 今までコメントの名前欄に一部の半角記号をトリップに使うと2ちゃんとは違うトリップが生成されていたのが完全に同じ物になりました。・・・といってもコメント欄でトリップを使っているのは私だけですけど・・・

 一応、作り直したトリップ関数を掲載しておきます。赤字の部分が修正した箇所です。
 ちなみにこの関数はeucかsjisの文字コードでしかうまく動かないはずです。utf-8等の文字コードを使用の場合は変更が必要です・・・たぶん

<?php
function trip($name) {
$trip = "";
$name =str_replace('◆','◇',$name);
$tripos = strpos($name, "#");
if ($tripos !== false) {
 $triname = substr($name,$tripos+1);
 $triname = mb_convert_encoding($triname, "Shift_JIS", "auto");
 $name = substr($name,0,$tripos);
 $salt = substr($triname.'H.',1,2);
 $pattern = '/[¥x00-¥x2D¥x7B-¥xFF]/';
 $salt = preg_replace($pattern,".",$salt);
 $patterns = ":;<=>?@[¥¥]^_`";
 $mach = "ABCDEFGabcdef";
 for($i = 0; $i <= 13 - 1; $i++){
  $salt = str_replace($patterns[$i], $mach[$i], $salt);
 }
 $trip = crypt($triname,$salt);
 $trip = substr($trip,-10);
 $trip = '◆'.$trip;
}
return $name.$trip;
}
?>

投票コメント機能製作メモ26

 今回拍手の集計ページで過去の投票を集計して、累計に書き込み、計算済みのデータを削除するというスクリプトを書きました。
 mysqlで2つのテーブルの内一方の内容に集計関数を使って、もう一方のテーブルの内容をupdate文で変更するにはサブクエリを使うようですが、ググって調べた内容では更新しない行にヌルが入って役に立ちませんでした。色々考えつつAccessクエリのsqlビューを見たり、mysqlの入門書を見たりした所、テーブルの内部結合をしてサブクエリを使えば良いだろうと考えつきました。

settei.phpには
define("TITLE","taitoru");  //タイトルテーブルの名前
define("HYOU","tokuhyou");  //得票テーブルの名前
という行を入れてます。

<?php
require "settei.php";

//WHERE句で使う日付条件を変数に格納
$hiduke = "tdate < SUBDATE(CURDATE(),INTERVAL 32 DAY)";

$syuukei_res = mysql_query("UPDATE ".TITLE." 
//内部結合
  INNER JOIN ".HYOU." ON ".TITLE.".tcode = ".HYOU.".tcode
//サブクエリでアップデート
  SET tokuhyou = ( SELECT COUNT(*) + tokuhyou FROM ".HYOU."
  WHERE ".HYOU.".tcode = ".TITLE.".tcode AND ".$hiduke."
  GROUP BY ".HYOU.".tcode )
//サブクエリの外側のWHERE句でヌルを回避
  WHERE ".$hiduke);

if (!$syuukei_res) {
  echo mysql_error(),"<br>";
  die("データ更新エラー<br>");
} else {
//古いデータの削除
  $syuukei_res = mysql_query("DELETE FROM ".HYOU." WHERE ".$hiduke);
  if (!$syuukei_res) {
    echo mysql_error(),"<br>";
    die("データ削除エラー<br>");
  } else {
    echo "拍手データ累計に加算";
  }
}
?>

 これからサイトを更新する時に毎回このスクリプトを実行するようにします。他の誰かにのスクリプトのファイル名を知られて実行されても何の害も出ません。

まとめサイト作成支援セットアップ

  前々から話していた「まとめサイト作成支援セット」がベクターからダウンロードできるようになりました。
 フリーウェアなので無料で使えますよ。こっそり「寄付歓迎」にチェックを入れたら、寄付を募っています、みたいな表示がされてちょっと恥ずかしい・・・ベクターは登録ソフトに事前にウィルスチェックをするので、安心して使ってみて下さい。

投票コメント機能製作メモ25

 それでは、コメントを表示する関数を使ったコメントページです。
 コメントに書いているように少し改造すれば掲示板に出来そうですが、コメントの制限文字数と掲示板の制限文字数は同じで良いのか?とか○○拍手は掲示板では消さなくてはいけないとか、掲示板ならレス数に上限を設けなくてはいけない等々。掲示板とコメントの区別は何処でするか?新しく変数を作るかid10000以上をコメント、未満を掲示板とする考えも有りますが汎用的でなないような。色々と迷いが有って掲示板スクリプトを作る所までいきません。
 それとは別にフリーウェアとして公開するつもりなら、コメントページや集計ページはカスタマイズがしやすくなくてはならない、と思います。私のデザインは何か地味なので・・・・。htmlのテンプレートを読んで、その中にコメントや集計を書く方式にすればカスタマイズも容易かと思います。重くならないかという心配も有りますが・・・
 とりあえずコメントの表示部分までは作り直したので、以後しばらくは公開済みの体験談ページの文字列を一括変換して入力フォームを変更するソフトを作る事にします。一般公開できるのはまだまだ先のようです。

 もしここまでを読んで、まとめサイトで使っている人気投票やコメントのスクリプト、ページ追加ソフトが欲しいという人が有りましたら、不完全な物ですがメールにて提供します。

comment.php
require "settei.php"; //設定ファイルの挿入
require "countcom.php";  //コメント数を数える関数挿入

$nflg = "1"; //表示フラグ
$flg = "1";  //ダミー変数
$cnt = "0";  //コメントの数
$page = MAX_NUM; //表示するページ

//POSTされた
if ($_SERVER["REQUEST_METHOD"]=="POST") {
  session_start();
  $id = $_POST["id"];            //タイトル番号
  $kflg = $_POST["kflg"];        //コメント有り="1"
  $namae = htmlspecialchars_decode($_POST["namae"],ENT_QUOTES); //名前
  $komento =htmlspecialchars_decode($_POST["komento"],ENT_QUOTES); //コメント
  if ($komento =="") $kflg = "0";
} else {              //GETで呼ばれた
  $id = $_GET["id"];   //話の番号
  $kflg ="0";          //コメント無し="0"
  if (isset($_GET["page"])) $page = $_GET["page"];  //ページ番号が指定された
}

$kakunin ="0"; //確認ページではない
$pflg = "1";
require "comcheck.php";
if ($nflg == "1") {
  $tokuhyou_res = mysql_query("SELECT count(*) FROM ".HYOU." WHERE tcode = '$id'");
  if ($tokuhyou_res != false) {
    $tokuhyou = $tokuhyou + mysql_result($tokuhyou_res,0); //得票数合計
    mysql_free_result($tokuhyou_res);  //リソースの開放
  }
  $taitoru = "【" .$taitoru. "】へのコメント";
}
//ページタイトル設定
echo "<html><head>";
echo "<meta http-equiv=¥"Content-Type¥" content=¥"text/html; charset=shift_jis¥">";
echo "<head><meta http-equiv=¥"Content-Type¥" content=¥"text/html; charset=shift_jis¥">";
echo "<title>",$taitoru,"</title>";
?>
</head><body>
<div align="center">
  <center>
 <font size=5>
<?php
echo $taitoru,"</font><br>";
echo "$tokuhyou 拍手<br>";
?>
  <table border="1" width="700" bgcolor="#FFFFFF">
    <tr>
      <td width="100%">
      </center>
<?php
//コメントの登録処理
switch ($kflg) {
  case "1":   //登録するコメント有り
    if ($_SESSION['execute']) break;
    $namae = htmlspecialchars(trip($namae),ENT_QUOTES);
    $komento = htmlspecialchars($komento,ENT_QUOTES);
    $komento = nl2br($komento);
    //同じ話の番号の中でコメント番号の最大値を取得
    $komento_res = mysql_query("SELECT MAX(knum) FROM ".COMMENT." WHERE tcode = '$id'");
    if (!$komento_res) {
      $msg = $msg . "データベースのアクセスに失敗しましたorz<br>";
      $nflg = "0";
      break;
    } else {
      $kbango = mysql_result($komento_res,0) + 1; //コメント番号の作成
      $komento = str_replace("¥¥","¥¥¥¥",$komento);  //MySQLでエラーに
      $namae = str_replace("¥¥","¥¥¥¥",$namae);      //ならないように
      $ipnum = ip2long($ipadr);  //IPアドレスを整数値に変換
      $komento_res = mysql_query("INSERT INTO ".COMMENT." (tcode,knum,kname,ktime,ktext,kipadr,khost)
        VALUES ('$id','$kbango','$namae',CURRENT_TIMESTAMP(),'$komento','$ipnum','$host')");
      if (!$komento_res) {    //↑データベースにコメントを追加する処理
        $msg = $msg . "コメントの登録に失敗しました<br>";
        $nflg = "0";
        break;
      }
      $_SESSION['execute'] = true;
    }
}
if ($nflg == "0") {  //エラー有り
  echo $msg;  //エラーメッセージ
} else {
  //コメント表示
  require "putcom.php";
  $com_kazu = countcom($id);
  $page_suu = floor($com_kazu / PAGE_COM);
  if ($com_kazu % PAGE_COM != 0) $page_suu++;
  if ($page == MAX_NUM) $page = $page_suu;
  if ($page == 0 || $com_kazu <= PAGE_COM) {
    $cnt = putcom($id,0,0);  //コメント全表示
    if ($cnt ==0) echo "まだコメントは有りません<br>";
  } else {
    $offset = ($page - 1) * PAGE_COM;
    $cnt = putcom($id,$offset,PAGE_COM);  //コメント1ページ分表示
    echo "<Div Align=¥"center¥"><a href=¥"comment.php?id=$id&page=0¥">全</a>";
    if ($page !=1) {
      echo " <a href=¥"comment.php?id=$id&page=1¥">頭</a>";
      echo " <a href=¥"comment.php?id=$id&page=",$page -1,"¥">前</a>";
    }
    for ($i=1;$i<=$page_suu;$i++) {
      if ($i == $page) {
        echo " $i";
      } else {
        echo " <a href=¥"comment.php?id=$id&page=$i¥">$i</a>";
      }
    }
    if ($page != $page_suu) {
      echo " <a href=¥"comment.php?id=$id&page=",$page + 1,"¥">次</a>";
      echo " <a href=¥"comment.php?id=$id&page=$page_suu¥">新</a>";
    }
    echo "</Div> ";
  }
//この辺にコメント入力フォームを入れると掲示板になりそう
}
?>
    </td>
  </tr>
  </table>
<?php
if ($nflg == "1") {
  echo "<br><a href=¥"../",$turl,"¥">体験談へ戻る</a><br><br>";
}
?>
      <a href="../menu1.htm">1列メニュー</a>&nbsp; <a href="../">Top</a>
</div></body></html>


投票コメント機能製作メモ24

 たしか画像に拍手と書いたweb拍手方式の投票を実装するだけのはずが、いつの間にか投票コメント機能の全面書き換えになってる・・・・なんでだろう?
 コメント表示ページを作り直すに当たってコメントの表示部分だけを関数化しておきます。そうすると後々複数ページに別けて表示したり、掲示板に応用ができそうです。

define("MAX_NUM",9999);  //便宜上の最大値
 設定用ファイルにこの1行を追加しておきます。コメント数の上限という意味が無くもないですが、MySQLの扱うレコード数の上限はOSの制限やディスク容量で決まるという事なので、コメント数には上限を設けません。便宜的に最大値を現す数値が有ると都合が良いのです。
 この関数は話の番号、読み飛ばすレコード数(オフセット)、表示するコメント数を引数とし、実際に表示した数を返します。

putcom.php
<?php
function putcom($id,$ofs,$kazu) {
  $limit = "LIMIT $ofs,";
  if ($kazu ==0) {$limit = $limit . MAX_NUM;} else {$limit = $limit . $kazu;}
  $cnt = "0";
  $youbi = array("(日) ","(月) ","(火) ","(水) ","(木) ","(金) ","(土) ");
  $komento_res = mysql_query("SELECT tcode,kbflg,knum,kname,kipadr,
  DATE_FORMAT(ktime,'%Y/%m/%d') AS hizuke,DATE_FORMAT(ktime,'%w') AS youbi,
  DATE_FORMAT(ktime,'%H:%i:%s')AS jikoku,ktext FROM ".COMMENT." WHERE tcode =
  '$id' AND kbflg = 0 ORDER BY knum,ktime $limit"); //コメントテーブルから取り出し
  if (!$komento_res) {
    echo "データベースに異常が発生しました。<br>";
  } else {
    while($komento_tbl = mysql_fetch_array($komento_res)) {
      echo "<p class=¥"MsoNormal¥" style=¥"text-indent: -30pt;";
      echo "margin-left: 35pt;line-height: 115%; margin-top: 0; margin-bottom: 10.5pt¥">";
      echo $komento_tbl["knum"] + K_GETA," 名前:<b><font color='Green'>";
      if ($komento_tbl["kname"] != "") echo $komento_tbl["kname"]; else echo NANASHI;
      echo "</font></b> 投稿日:",$komento_tbl["hizuke"];
      echo $youbi[$komento_tbl["youbi"]],$komento_tbl["jikoku"];
      echo " ID:",substr(trip("#" . substr($komento_tbl["hizuke"],6,4) . (floor(abs($komento_tbl["kipadr"]) / 256))),-9);
      echo "<br>",$komento_tbl["ktext"];
      echo "</p>";
      $cnt += "1";
    }
  mysql_free_result($komento_res);  //リソースの開放
  }
return $cnt;
}
?>

 この関数を使ってコメントを表示するページを一応作ったのですが、割と簡単に掲示板スクリプトに応用ができそうで、書き直して同じファイルでコメントと掲示板の両方に対応させようか、コピーして一部を書き換えて掲示板用ファイルをつくるべきか、共通部分を関数化して全面的に書き換えるべきか迷っています。参考までにテストページにアップしておきます。テスト用なので1ページのコメントを15にしています。正式運用時には20前後が良さそうな気がしています。これでコメントの数が多くなって携帯で読めなくなる日が来る心配がなくなります。


投票コメント機能製作メモ23

 既にテストページに公開している確認ページです。input type="submit"でボタンを2つ用意したらどうなるか?と思っていたのですが、クリックされたボタンの名前だけが変数にセットされてクリックされなかったボタンの名前は変数にセットされないのが分かりました。なので画像ボタンの時と同様に
if (isset($_POST["hakusyu"])) $tflg="1";
とすれば良く、ソースの変更も最小限で済みました。

kakunin.php
<?php
$pflg = "0";   //POSTされたら"1" そうでなければ"0"
$tflg = "0";   //投票のフラグ "1"投票有り "0"投票無し
$kflg = "1";   //コメントのフラグ "1"コメント有り "0"コメント無し
$kakunin ="1"; //確認ページなら"1"

require "settei.php";  //設定ファイルの挿入
require "countcom.php"; //コメントを数える関数挿入

//POSTされた
if ($_SERVER["REQUEST_METHOD"]=="POST") {
$pflg = "1";
//変数へ代入
$id = $_POST["id"];    //タイトル番号
$namae = $_POST["namae"];        //名前
$komento = $_POST["komento"];    //コメント
if ($komento =="") $kflg = "0";
if (isset($_POST["hakusyu"])) $tflg="1";  //拍手ボタンクリック
}
switch ($tflg) {   //得票テーブルに追加
  case "1":
    $ipadr = getenv("REMOTE_ADDR"); //IPアドレス取得
    $ipnum = floor(ip2long($ipadr)/256);  //IPアドレスを整数値に変換
    $tokuhyou_res = mysql_query("SELECT tcode , tipadr FROM ".HYOU." WHERE tcode = '$id' AND tipadr = '$ipnum'",$my_con);
    if (!$tokuhyou_res) break;  //id番号違い
    if(!mysql_fetch_array($tokuhyou_res)) {  //同じIPの投票が無かった
      $touhyou_res = mysql_query("INSERT INTO ".HYOU." (tcode,tdate,tipadr) VALUES ('$id',CURDATE(),'$ipnum')",$my_con);
    }
  mysql_free_result($tokuhyou_res);  //リソースの開放
}
require "comcheck.php";
session_start();
?>

<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis">
<title>確認</title></head><body><p> </p>
<div align="center">  <center>
  <table border="1" width="700" bgcolor="#FFFFFF">
    <tr>      <td width="100%">
      </center>
      <p class="MsoNormal" style="text-indent: 10.5pt; mso-char-indent-count: 1.0; mso-char-indent-size:10.5pt;line-height: 115%; margin-top: 0; margin-bottom: 0" align="left">

<?php
//次のページに行くかどうか
if ($nflg == "0") {
  echo $msg," ブラウザの戻るボタンで前のページへ戻って下さい<br>";
} else {
  $_SESSION['execute'] = false;
  $namae = htmlspecialchars($namae,ENT_QUOTES);
  $komento = htmlspecialchars($komento,ENT_QUOTES);
  echo $msg,"<hr> これでよろしければ【送信する】ボタンをクリックして下さい<br><br>";
  echo " やり直したければブラウザの戻るボタンで前のページへ戻って下さい";
  echo "<form action=¥"comment.php¥" method=¥"POST¥">";
  echo "<input type=¥"hidden¥" name=¥"id¥" value=¥"$id¥">";  //タイトル番号の送信
  echo "<input type=¥"hidden¥" name=¥"kflg¥" value=¥"$kflg¥">";        //コメントの有無の送信
  echo "<input type=¥"hidden¥" name=¥"namae¥" value=¥"$namae¥">";      //名前の送信
  echo "<input type=¥"hidden¥" name=¥"komento¥" value=¥"$komento¥">";  //コメントの送信
  echo "   <input type=¥"submit¥" name=¥"submit¥" value=¥" 送信する ¥">"; //送信ボタン
  echo "</form>";
}
?>
</td></tr></table></div></body></html>

 名前の変数名をnamaeにしたせいでnameとよく間違えるというのは置いといて、前半部分は主に拍手ボタンがクリックされた時の処理です。ここで投票用のテーブルにデータを追加しています。データにはipアドレスを32ビットの数値にしたものを256で割って記録しています。これで同じ人が複数回投票するのを防いでいます。ただ重複投票防止策としては大雑把に過ぎるような気もしていて改善の余地有りです。
 前半部分の最後、htmlタグの前の部分にsession_start();という行が有りますが、これはページをまたいで使える変数を使う宣言ですね。コメント表示ページに登録機能を付けたらリロードする度に同じ内容が追加されるようになったので、対策としてそういった変数を使うことにしました。後半部分で使っている $_SESSION['execute'] = false;というのです。コメント登録部分でこの値をtrueにして、登録するかどうかを判定します。
 コメントの中身が適切かどうか判定する部分は登録用のスクリプトで再び使うので別ファイルに書いてrequire "comcheck.php";として読み込ませています。

comcheck.php
<?php
require "trip.php";  //トリップ関数挿入
$nflg = "1";    //次ページへのフラグ "1"なら次へ"0"なら戻らせる
$youbi = array("日","月","火","水","木","金","土");
switch ($pflg) {
  case 0:  //ポストされてない
    $msg = "直接見ても何もないよ<br>";
    $nflg = "0";
    break;
  case 1:  //ポストされた
    //タイトル番号チェック
    if (!is_numeric($id)) {
      $msg = "タイトル番号の記述を間違えましたorz<br>";
      $nflg = "0";
      break;
    }
    $my_title = mysql_query("SELECT tcode , tname , turl ,tokuhyou FROM ".TITLE. " WHERE tcode = '$id'",$my_con);
    if (!$my_title) {
      $msg = "データベースのアクセスに失敗しましたorz<br>";
      $nflg = "0";
      break;
    }
    $tnamae = mysql_fetch_array($my_title);
    if (!$tnamae) {
      $msg = "このタイトルは登録されていませんorz<br>";
      $nflg = "0";
      break;
    }
    //データベースに話が登録されていた
    $taitoru = $tnamae["tname"];
    $turl = $tnamae["turl"];
    $tokuhyou = $tnamae["tokuhyou"];
    mysql_free_result($my_title);  //リソースの開放
    if ($kakunin == "1") {  //確認ページに挿入された
      if ($kflg == "0") {  //コメント無し
        if (countcom($id) =="0") {       //登録済みコメント無し
          header( "location: ../$turl" );        //体験談ページへ移動
          exit;
          }  else {
          header( "location: comment.php?id=$id" );
          exit;
        }
      }
    }
    if ($kflg =="0") break;
    $msg = "<b>".$taitoru."</b><br>";  //話のタイトル
     require "kinshi.php";  //アク禁NGワードチェックファイルの挿入
    if ($akflg == "1") {
      $msg = $msg . "<b><font color='Red'> あなたからの書き込みは拒否されました<br>";
      $kflg = "0";
      $komento = "";
      $nflg = "0";
      break;
    }
    if ($ngflg == "1") {
      $msg = $msg . "<b><font color='Red'> 不適切な書き込みはご遠慮ください<br>";
      $kflg = "0";
      $komento = "";
      $nflg = "0";
      break;
    }
    //名前チェック
    if (strlen($namae) > N_NAGASA) {
      $msg = $msg . "<b><font color='Red'> 名前の文字が長すぎます<br>";
      $msg = $msg . " 全角で". (N_NAGASA / 2) ."文字以内でお願いします。</font></b><br>";
      $nflg = "0";
      break;
    }
    //コメント内容チェック
    if ($kflg==1) {
      $msg = $msg . "<br> コメント内容<br>";
      $msg = $msg .  "<p class=¥"MsoNormal¥" style=¥"text-indent: -30pt;";
      $msg = $msg .  "margin-left: 35pt;line-height: 115%; margin-top: 0; margin-bottom: 10.5pt¥">";
      $msg = $msg .  "xxxx 名前:<b><font color='Green'>";
      if ($namae == "") $namae = NANASHI;
      $msg = $msg .htmlspecialchars(trip($namae));
      $msg = $msg . "</font></b> 投稿日:";
      $ktime = time();
      $msg = $msg .  date("Y/m/d(",$ktime).$youbi[date("w",$ktime)].date(") H:i:s", $ktime)."<br>";
      if (strlen($komento) <= K_NAGASA) {
        $msg = $msg .  nl2br(htmlspecialchars($komento))."<br></p>";
      } else {
        $msg = $msg .  "<b><font color='Red'>コメント内容が長すぎます<br>";
        $msg = $msg .  "全角で".( K_NAGASA/2) ."文字以内でお願いします</font></b></p>";
        $nflg = "0";
        break;
      }
    }
}
?>

 確認ページには不要な変数をセットしたりしていますが、コメント登録ページにも使うのでまっいっかという事にしています。関数化しないファイルを挿入するのはプログラムの流れが読みにくくなるので余りするべきではありませんが・・・・まっいっか。メッセージは後でまとめて表示する必要から一旦$msgという変数に格納しています。
 NGワードやアク禁の処理は今の所たいした事はしていません。これも関数化せずに$akflgと$ngflgが"1"ならコメントをはじくようにしています。

kinshi.php
<?php
$ipadr = getenv("REMOTE_ADDR");
$host = getenv("REMOTE_HOST");
if ($host == null || $host == $ipadr) $host = gethostbyaddr($ipadr);
$akflg = "0";
$ngflg = "0";
if (strpos($komento,"XXXXX") !== false) $ngflg="1";
?>

 ホスト名とipアドレスを取得していますが、アク禁処理は今の所何もしていません。具体的なNGワードはXXXXXの所に記述し、増える度に同様の行を増やして行く予定です。いずれはNGワードやアク禁情報はデータベースに記録し、管理者専用ページから設定できるようにするべきだと思っています。


投票コメント機能製作メモ22

  画像ファイルを送信ボタンに使うスクリプトができたので、朝のうちにテストページにアップしたのですが、携帯で動作確認をしたら、ボタン画像になるはずの部分がテキストボックスになっていました。ググって調べたところ、携帯のブラウザはフルブラウザでないとinput type="image"をサポートしていないそうです。う〜ん・・・洒落怖のまとめのように携帯用とPC用が別サイトになっていれば、このスクリプトでも使えたのですが・・・
 気を取り直して、ボタンを2つ用意する考えは悪くないと思うのでinput type="submit"で、「拍手する」ボタンと「拍手しない」ボタンを用意して、拍手数はコメント数と同様に画像をボタンっぽくないものに変更し、そこに表示する事にします。仕様が似ているので変更には大した手間は掛からないでしょう。そんな訳でソースの公開は修正が終わってからにします・・・参考にしている人が居るのかどうかは知りませんが・・・

投票コメント機能製作メモ21

 さて、昨日のイメージボタン2個を送信ボタンとして使う処理です。
体験談ページのフォームタグの
<input type="submit" name="submit" value="投票/コメントする">
を消して変わりに
<input type="image" src="../touhyou/button.php?id=439" name="hakusyu" alt="拍手して送信">
<input type="image" src="../touhyou/nobutton.gif" alt="拍手無し送信"> ←どちらかで送信
の2行を追加します。nobutton.gifはボタン画像に「拍手しない」と書いたgifファイルです。
拍手ボタンの名前はhakusyuになっています。

 それで、簡単なスクリプトを書いて実行したところ、hakusyuボタンをクリックして送信した場合hakusyu_xとhakusyu_yという変数が作られ、それぞれに座標の値が入るのが分かりました。拍手しないボタンがクリックされた場合はこの変数は作られず、拍手してないボタンの座標の入った別の変数が作られます。今回はボタンは2個だけで、送信ボタンの代わりに使うわけですから、座標の内容はどうでもよく、変数hakusyu_xが作られているかどうかを調べれば良い事になります。
具体的にはこんなスクリプトになります。

$tflg = "0";   //投票のフラグ "1"投票有り "0"投票無し
if (isset($_POST["hakusyu_x"])) $tflg="1";  //拍手ボタンクリック

 拍手ボタンがクリックされたかどうかを判定して投票テーブルに追加する処理を今回は確認ページでする事にして、登録に掛かる時間を分散します。今までは確認ページから送信ボタンをクリックしたら登録用スクリプトファイルを実行し、コメントページへジャンプしていましたが、どうも登録してからコメントを表示するまで時間が掛かる事があって2度ボタンをクリックする人が居るようなので、登録作業もコメント表示ファイルで実行し、画面が早く切り替わるようにしようと考えています。とりあえず、確認ページは作り終わっているのですが、コメントページの登録部分と重複するスクリプトが有ってファイルを分割しようかどうかの検討中でテストページへのアップにはいたりません。

投票コメント機能製作メモ20

 さて、昨日は良い案が有ったら教えてください等と弱気な事を書いていますが、少なくとも現在より多少手間が省けてパケ代の節約になる仕組みを考えてみました。

・拍手ボタンと「コメントのみ」ボタンの二つを用意する
・拍手ボタンをクリックすれば当然一票投票した事にする
・コメントが入力されていればどちらのボタンがクリックされてもコメントページへ
・コメントが未入力でも過去のコメントが有ればどちらのボタンがクリックされてもコメントページへ
・コメントが無ければ体験談ページをリロード
・コメント未入力で過去のコメントが有る場合は確認ページを省略

 大体こんな所ですかね。画像ボタンをsubmitボタンの代わりに使うと、座標が渡されるとかどうとか、どちらのボタンがクリックされたか調べるのはどうするんだ?とかよく分かっていませんけど。テスト用のスクリプトを書いて実行してみないと分からないですね。

 それとは別に、コメント数を表示するスクリプトを作りました。拍手表示の応用ですけど。

comcnt.php
<?php
$id = $_GET["id"];      //話の番号
require "settei.php";   //設定ファイルの挿入
require "imageput.php"; //imageput関数の挿入
require "countcom.php"; //コメントを数える関数挿入

$moji = "(". countcom($id) .")";

imageput($moji,$haikei,4);
?>

countcom.php
<?php
function countcom($id) {
$comment_res = mysql_query("SELECT count(*) FROM ".COMMENT." WHERE tcode = '$id' AND kbflg = 0");
if ($comment_res != false) {
  $moji = mysql_result($comment_res,0); //コメント数
  } else {
  $moji = 0;
  }
return $moji;
}
?>

例によってテストページのhtml書に貼り付けています。
<img border="0" src="../touhyou/comcnt.php?id=439" width="45" height="16">
widthとheightは指定しなくても良かったと思いますけど、FrontPageが勝手に入れたみたい。
 前回作ったimageput関数は文字の縦位置を指定できるように変更しました。

imageput.php
function imageput($mojiretu , $address) {  →  function imageput($mojiretu , $address , $y) {
Imagestring($image,3,6,1,$mojiretu,$black); → Imagestring($image,3,6,$y,$mojiretu,$black);

button.php
imageput($moji,$button); → imageput($moji,$button,1);


投票コメント機能製作メモ19

 先日書いた拍手用画像スクリプトですが、表示する日本語が"拍手"の2文字だけなのに、フォントファイルを用意するのは効率が悪いと思い拍手の文字はgif画像に埋め込むように変更しました。
 更に、今までテーブルの名前をそのままプログラムに書き込んでいた為、複数のまとめサイトを同一データベースで投票コメント機能を実現するには個別のファイルのテーブル名を書き直さなくてはいけないという欠点が有りました。複数のデータベースを使えば書き換えは最小限で済むのですが、汎用性を考えてテーブルの名前は設定用ファイルに書き込むように変更します。

まずは設定ファイルから
settei.php
<?php
//コメントの設定
define("NANASHI","なんか笑える名無し"); //名無しのデフォルト
define("N_NAGASA", 40);  //名前欄の最大長
define("K_NAGASA", 500); //コメントの最大長
define("K_GETA", 1000);  //コメント番号に足す数
//テーブル名の設定
define("TITLE","taitoru");  //タイトルテーブルの名前
define("HYOU","tokuhyou");  //得票テーブルの名前
define("COMMENT","komento"); //コメントテーブルの名前
//gif画像の設定
$button = "button.gif";   //ボタンのgif画像のパス
$haikei = "haikei.gif";   //コメント数の背景(透明)

//データベースの設定
$my_server = "xxxxxx.xxxxx.jp";  //サーバ名
$my_db = "xxxxxxx";   //データベース名
$my_id = "xxxxxxx";   //ユーザー名(ID)
$my_pw = "******";       //パスワード

@include "../../../test.php"; //テスト環境の設定(web上に転送されないないパスに置く)

//サーバー接続
$my_con = mysql_connect($my_server,$my_id,$my_pw);
if ($my_con == false)  die("MYSQLの接続に失敗しました。");

//データベースに接続
if (mysql_select_db($my_db,$my_con)) {
//  echo "データベースを選択<br>";
} else {
  die("データベースの選択失敗");
}
?>

 投票結果の表示行数や最近のコメントの表示行数等もこの設定ファイルに書き込んだ方が良さそうですが、それはまた後ほど・・・
 テスト環境の自分のPCのApach+mySQLでもレンタルサーバー上でも同じソースで動作するように
@include "../../../test.php";  の1行を加えています。
私のテスト環境ではマイドキュメント¥My Websがローカルホストとして認識され、マイドキュメント¥My Webs¥myweb1をレンタルサーバーに転送するようにしています。なので"マイドキュメント¥My Webs¥test.php"というファイルはテスト環境には存在して、レンタルサーバー上には存在しないファイルになります。
include文のWarningメッセージが出ると期待通りの動作にならないので@マークを付けて表示を抑制しています。

test.php
<?php
//データベースの設定
$my_server = "localhost";  //サーバ名
$my_id = "koba";      //ユーザー名(ID)
$my_pw = "koba";      //パスワード
$my_db = "touhyou";   //データベース名
?>

では書き直した拍手画像表示のファイルを
button.php
<?php
$id = $_GET["id"];      //話の番号
require "settei.php";   //設定ファイルの挿入
require "imageput.php"; //imageput関数の挿入

$flg = "1";

switch ($flg) {     //得票数ゲット
  case "1":
  $taitoru_res = mysql_query("SELECT tcode,tokuhyou FROM ".TITLE." WHERE tcode = '$id'",$my_con);
  if (!$taitoru_res) break;
  $taitoru_tbl = mysql_fetch_array($taitoru_res);
  if (!$taitoru_tbl)  break;
  $tokuhyou = $taitoru_tbl["tokuhyou"]; //得票累計(今は常に0)
  $tokuhyou_res = mysql_query("SELECT count(*) FROM ".HYOU." WHERE tcode = '$id'");
  if ($tokuhyou_res != false) $tokuhyou = $tokuhyou + mysql_result($tokuhyou_res,0); //得票数合計
  mysql_free_result($tokuhyou_res);  //リソースの開放
}
mysql_free_result($taitoru_res);  //リソースの開放

$moji = substr("    ".$tokuhyou,-4,4);  //数字の頭に空白を付けて4桁に

imageput($moji,$button);
?>

画像の合成関数は別ファイルとしました。
imageput.php
<?php
function imageput($mojiretu , $address) {
$image = imagecreatefromgif($address);
header("Content-type: image/gif");

$black = imagecolorallocate($image, 0,0,0);
Imagestring($image,3,6,1,$mojiretu,$black);
Imagegif($image);
ImageDestroy($image);
}
?>

文字を書き込む関数がImageTTFTextからImagestringに変わっています。

勢いでボタンをクリックした後に投票数を追加するすスクリプトも作りました。
touhyou.php
<?php
$id = $_GET["id"];      //話の番号
require "settei.php";  //設定ファイルの挿入

$flg = "1";
switch ($flg) {   //得票テーブルに追加
  case "1":
    $ipadr = getenv("REMOTE_ADDR"); //IPアドレス取得
    $ipnum = floor(ip2long($ipadr)/256);  //IPアドレスを整数値に変換
    $tokuhyou_res = mysql_query("SELECT tcode , tipadr FROM ".HYOU." WHERE tcode = '$id' AND tipadr = '$ipnum'",$my_con);
    if (!$tokuhyou_res) {
      break;
    }
    if(!mysql_fetch_array($tokuhyou_res)) {  //同じIPの投票が無かった
    $touhyou_res = mysql_query("INSERT INTO ".HYOU." (tcode,tdate,tipadr) VALUES ('$id',CURDATE(),'$ipnum')",$my_con);
  }
  mysql_free_result($tokuhyou_res);  //リソースの開放
}
switch ($flg){  //体験談url取得
  case "1":
    $taitoru_res = mysql_query("SELECT tcode,turl FROM ".TITLE." WHERE tcode = '$id'",$my_con);
    if (!$taitoru_res) break;
    $taitoru_tbl = mysql_fetch_array($taitoru_res);
    if (!$taitoru_tbl)  break;
    $turl = $taitoru_tbl["turl"];         //戻り先URL
    mysql_free_result($taitoru_res);  //リソースの開放
}
    header("location:../$turl");
    exit;
?>

 とりあえずテストページの画像にリンクを張ってボタンをクリックすると投票できるようにしてあります。
<a href="../touhyou/touhyou.php?id=439"><img border="0" src="../touhyou/button.php?id=439"></a>
 これがテストページのボタン画像部分のhtmlソースです。一応これで拍手方式の人気投票機能はできた事になりますが、困った事に拍手ボタンをクリックした後に同じページを再度読み込んでしまいます。てっきりブラウザのキャッシュにヒットして再読み込みしないのかと思っていました。
 投票とコメントの両方すると、体験談ページ→拍手で投票→体験談ページ→コメント入力→コメントページ→体験談ページ→次のページとなって、最初の閲覧と合わせて体験談ページを三度読み込む事になってしまいます。現在の投票方法でも体験談ページを二度読みますが、拍手方式の利点は投票とコメントを分離して投票のみしたい人の手間を省く事だと考えていたのですが、これだと両方したい人は手間が余計に掛かる事になります。PCで閲覧していればそれほど問題無さそうですが、携帯だとパケ代が余計に掛かってしまいます。う〜ん・・・どうした物か・・・今の方式がベストなのか・・・良い案が有ったら教えて下さい。


| 1/4PAGES | >>

calendar

S M T W T F S
   1234
567891011
12131415161718
19202122232425
262728293031 
<< March 2017 >>

笑える霊体験まとめサイト
の表紙作成に使ったソフト

Poser 10

新品価格
¥14,316から
(2014/4/9 14:19時点)

広告だったり

オリジナル電子書籍

selected entries

categories

archives

recent comment

links

profile

search this site.

others

mobile

qrcode

powered

無料ブログ作成サービス JUGEM