2012年3月1日木曜日

アクセスカウンタ(受講者Tの場合)

昨日の授業でやったアクセスカウンタのクラス化の部分のソースを晒します。

まずはソース全体です
access.class.php
<?php
class access {
 //アクセスカウンタ設定用
 private $counter_setting = array(  'mode' => 1        //カウンタ文字の表示形式(1:画像 2:文字)
          ,'img_dir' => 'img/'     //イメージディレクトリのパス
          ,'yesterday_digits' => 3    //昨日のカウンタ桁数
          ,'today_digits' => 3     //今日のカウンタ桁数
          ,'all_digits' => 5      //全体カウンタ桁数
          ,'ipcheck' => "y"      //IPをチェックするか(y:YES n:NO)
          ,'system_path' => "access_counter"  //システムのルートディレクトリ名
 );
 /*********************************
  * コンストラクタ
  **********************************/
 public function access(){
  //mysql に接続する
  $db = mysql_connect('localhost','tanaka','tanaka');

  // データベースを選択する
  $sdb = mysql_select_db('smarty_bbs');


 }
 /*********************************
  * アクセスカウンタ
  **********************************/
 public function counter($set  = ""){
  //設定があった場合変更する
  //print_r($set);
  if(is_array($set)){
   if(isset($set['mode'])){
    $this->counter_setting['mode'] = $set['mode'];
   }
   if(isset($set['img_dir'])){
    $this->counter_setting['img_dir'] = $set['img_dir'];
   }
   if(isset($set['yesterday_digits'])){
    $this->counter_setting['yesterday_digits'] = $set['yesterday_digits'];
   }
   if(isset($set['today_digits'])){
    $this->counter_setting['today_digits'] = $set['today_digits'];
   }
   if(isset($set['all_digits'])){
    $this->counter_setting['all_digits'] = $set['all_digits'];
   }
   if(isset($set['ipcheck'])){
    $this->counter_setting['ipcheck'] = $set['ipcheck'];
   }
   if(isset($set['system_path'])){
    $this->counter_setting['system_path'] = $set['system_path'];
   }
  }
  //今日の日付を取得する
  $today_date = date("Y-m-d");

  //昨日の日付を取得する
  $yesterday_date = date("Y-m-d",strtotime("-1day"));

  //IPアドレスを取得する
  $ip = @$_SERVER["REMOTE_ADDR"];

  //クエリを送信する
  $sql= "select count(*) from counter_log";
  //print $sql;
  $result = mysql_query($sql);
  $row = mysql_fetch_row($result);
  
  //counter_logテーブルに値があれば更新する。
  if($row[0] > 0){
   //counter_logテーブルの値を参照する
   $sql = "select * from counter_log";
   $result = mysql_query($sql);
   $row = mysql_fetch_array($result);
   //print_r($row);

   //DBから持ってきた値をそれぞれの変数に代入する。
   //比較用日付
   $key = $row['today_date'];

   //昨日のカウント
   $yesterday_cnt = $row['yesterday_count'];

   //今日のカウント
   $today_cnt = $row['today_count'];

   //総合カウント
   $all_cnt = $row['all_count'];

   //直前のIPアドレス
   $just_before_ip = $row['just_before_ip'];

   //IPチェックをする。且つIPアドレスが直前のIPと一致しない
   //もしくは、IPチェックしない
   if(($this->counter_setting['ipcheck'] == "y" && ($ip != $just_before_ip || $key != $today_date))
   || ($this->counter_setting['ipcheck'] == "n")){
    //ログの日付が今日ならカウントアップ
    if($key == $today_date){
     $today_cnt++;
    }else{//日付が変わったら今日のカウントを昨日のカウントにし、
     //今日のカウントの新しく1を入れる。
     //昨日じゃない(=昨日の日付でなければそれより前の日付ということ)なら昨日のカウンタに0を入れる
     $yesterday_cnt = ($key == $yesterday_date) ? $today_cnt : 0 ;
     //↑の三項演算子をif文で書くと
     /*if($key == $yesterday_date){
      $yesterday_cnt = $today_cnt;
      }else{
      $yesterday_cnt = 0;
      }*/
     $today_cnt = 1;
    }
    //合計カウントをカウントアップ
    $all_cnt++;
    //テーブルの値を更新する
    $sql  = "update counter_log set ";
    $sql .= "   today_date = '".$today_date."' \n";
    $sql .= " , yesterday_count = '".$yesterday_cnt."' \n";
    $sql .= " , today_count = '".$today_cnt."' \n";
    $sql .= " , all_count = '".$all_cnt."' \n";
    $sql .= " , just_before_ip = '".$ip."' \n";
    $sql .= "where \n";
    $sql .= " counter_id = ".$row['counter_id']." \n";

    $result = mysql_query($sql);
    //print $sql;
   }
  }else{//値が無ければ新規登録
   //counter_logテーブルに新規に値を入れる
   $sql = "insert into counter_log (today_date,today_count,all_count,just_before_ip)values('".$today_date."','1','1','".$ip."')";
   $result = mysql_query($sql);
   //print $sql;
  }

  //桁数整形
  //昨日の訪問者数
  $yesterday = sprintf("%0".$this->counter_setting['yesterday_digits']."d",$yesterday_cnt);
  //今日の訪問者数
  $today = sprintf("%0".$this->counter_setting['today_digits']."d",$today_cnt);
  //全体の訪問者数
  $all = sprintf("%0".$this->counter_setting['all_digits']."d",$all_cnt);

  //画像を出力するHTMLに置き換える
  if($this->counter_setting['mode'] == 1){
   //タグを取得
   $yesterday = $this->outhtml($yesterday,$this->counter_setting['img_dir']);
   $today = $this->outhtml($today,$this->counter_setting['img_dir']);
   $all = $this->outhtml($all,$this->counter_setting['img_dir']);
  }

  $return_html  = "昨日:".$yesterday;
  $return_html .= "今日:".$today;
  $return_html .= "合計:".$all;
  return $return_html;
 }

 /*********************************
  * アクセスカウンタ用画像置き換え関数
  **********************************/
 public function outhtml($cnt,$path){
  //img_tagを定義する
  $img_tag = "";
  //0.pngからwidthとheightを取得する
  $size = getimagesize($path."0.png");
  for($i = 0 ; $i < strlen($cnt);$i++){
   //左から1桁ずつ順番に取得する。
   $num = substr($cnt,$i,1);
   $img_tag .= "<img src='/".$this->counter_setting['system_path']."/".$path.$num.".png' alt='".$num."'".$size[3].">";
  }
  return $img_tag;
 }


 /**************************************************************
  *                 アクセスログ
  **************************************************************/
 public function log(){
  //アクセスログを格納する配列を初期化する。
  $in = array();
  //日時情報を配列に格納
  $in[0] = date("Y-m-d H:i:s");
  //アクセスされたページのURLを配列に格納
  $in[1] = str_replace(",",", ",@$_SERVER["REQUEST_URI"]);
  //どのページからリンクして来たかの情報を配列に格納
  $in[2] = str_replace(",",", ",@$_SERVER["HTTP_REFERER"]);
  //閲覧者のブラウザ情報を配列に格納
  $in[3] = str_replace(",",", ",@$_SERVER["HTTP_USER_AGENT"]);
  //IPアドレスを配列に格納
  $in[4] = str_replace(",",", ",@$_SERVER["REMOTE_ADDR"]);
  //ホスト名を配列に格納
  $in[5] = str_replace(",",", ",@gethostbyaddr($_SERVER["REMOTE_ADDR"]));

  //SQL作成
  $sql  = "";
  $sql .= "INSERT INTO access_log \n";
  $sql .= "(  \n";
  $sql .= "  access_time \n";
  $sql .= " ,access_url \n";
  $sql .= " ,access_referer \n";
  $sql .= " ,access_agent \n";
  $sql .= " ,access_ip \n";
  $sql .= " ,access_host \n";
  $sql .= ")values( \n";
  $sql .= " '".$in[0]."' \n";
  $sql .= ",'".$in[1]."' \n";
  $sql .= ",'".$in[2]."' \n";
  $sql .= ",'".$in[3]."' \n";
  $sql .= ",'".$in[4]."' \n";
  $sql .= ",'".$in[5]."' \n";
  $sql .= ") \n";
  //SQL発行
  $result = mysql_query($sql);

 }
}
?>

次に呼び出し部分
  //授業で作ったアクセスカウンタ
  //アクセスカウンタクラス
  require_once("./src/common/access.class.php");
  //==============================================================
  //アクセスカウンタ処理2
  //==============================================================
  $obj_access = new access();
  $html_counter = $obj_access->counter(array(  'mode' => 1
           ,'img_dir' => 'img/counter/'
           ,'yesterday_digits' => 4
           ,'today_digits' => 4
           ,'all_digits' => 6
           ,'ipcheck' => "y"
           ,'system_path' => "smarty-bbs"));

  $obj_access->log();

以下解説
================================================================
access.class.php
================================================================

2行目:
クラスの宣言です

3~11行目
メンバ変数counter_settingをプライベートで宣言しています。
counter_settingはアクセスカウンタで使う設定を連想配列化したものです。

15~23行目
コンストラクタです。
今回メインの機能2つともがDBを利用しているので先に接続しておきます。
すでに接続されている場合は接続先が同じ場合無視されるはずです。

27行目
アクセスカウンタの関数宣言です。
引数はsetのみですがここには連想配列で設定が入ってくることを想定しています。
入力されない場合はメンバ変数定義時に設定した数値がそのまま利用されます。
詳しくは呼び出しの部分のソースをご覧ください。

30~52行目
引数の値を受け取って設定を変更しています。

53~61行目
関数内で使う変数を初期化しています。
57行目は前日の日付を取得しています。

63~66行目
カウンタの個数を取得します。
今回は初期状態が0行、1回でもアクセスがあった場合1行が返ってきます。

71~73行目
値がある場合カウンタの値を取得します。

78~90行目
取得した値を変数に格納します。

94行目
IPチェック(同一のIPの場合連続でカウントしないためのチェック)がyesの場合で、
且つ現在アクセスしているIPが直前にアクセスしてきたIPと違う場合、もしくはDBに格納してある日付が今日の日付と違う場合にはカウント処理を行います。

95行目
もしくはIPチェックを行わない場合、カウント処理を行います。

97・98行目
DBに格納してある日付が今日の日付と同じ場合、本日のカウンタをカウントアップします。

99~109行目
日付が変わったら今日のカウントを昨日のカウントにし、
今日のカウントの新しく1を入れます。
昨日じゃない(=昨日の日付でなければそれより前の日付ということ)なら昨日のカウンタに0を入れます。

112行目
全体カウンタをカウントアップします

115~123行目
DBを更新します。

126~129行目
DBが0行の場合新しく追加します。

135~139行目
各カウンタをsprintfで整形します。

142~147行目
カウンタの各数値を画像タグに置き換える関数outhtmlを呼び出します

149~151行目
戻り値用の変数にカウンタを表示する文字列を格納します

152行目
戻り値を返します

158行目
アクセスカウンタで使用するouthtmlを宣言します
カウンタの各数値を画像タグに置き換える関数です。
第一引数のcntはカウンタの文字列(指定の桁数で整形された数値)
第二引数は画像の入ってるフォルダのパス

160行目
戻り値用変数(HTML化した文字列)の初期化

162行目
getimagesizeで画像のサイズを取得します

163~167行目
左から1桁ずつ数値を取得して
対応する画像を表示するIMGタグを戻り値用変数に格納します

168行目
戻り値を返します

175行目
アクセスログを取るための関数を宣言します

176~189行目
アクセスログを格納する配列を初期化します
str_replaceは文字列を置き換える関数です
例:
$in[1] = str_replace(",",", ",@$_SERVER["REQUEST_URI"]);
$_SERVER["REQUEST_URI"]の中から「,」を探して「, 」に置き換えたものを$in[1] に格納しています。

192~210行目
DBにログを格納する。

================================================================
呼び出し部分
================================================================
3行目アクセスクラスを読み込んでいます

7行目
アクセスクラスのインスタンス化をしています。
このときコンストラクタが動いてDBに接続されます。

8~14行目
アクセスカウンタを呼び出しています。
この時引数には連想配列で各設定項目を記述していますが必要に応じて書かないことも可能です。

16行目
アクセスログを取ります。

5 件のコメント:

  1. ありがとうございます
    参考にします^^

    返信削除
  2. 参考にさせていただきます!

    返信削除
    返信
    1. ありがとうございます。
      おかしいところなどありましたら、ご指摘いただけると助かります。

      削除
  3. まるっと、頂きました。
    勉強させて頂きます。
    ありがとうございました。

    返信削除