[[PukiWiki]]
#contents
* 概要 [#u24a71e4]
MySQLを使ったpukiwiki用のアクセスカウンターです。
一言でいえば、pukiwikiのページ名ごとに、アクセス情報を保存しているだけです。
* インストール [#va5b3c26]
以下の手順でインストールできます。
** 免責 [#g4423f14]
本スクリプトをご利用なさる場合は、万一トラブルが発生しても責任は負いかねますので、自己責任にてご利用ください。
** ダウンロード [#a1402b24]
このページに添付してある「pukiwiki_db_counter.zip」をダウンロードして解凍します。
&ref(pukiwiki_db_counter.zip);
** データベースのテーブル作成 [#oaca2e7a]
MySQLにアクセスカウンター用のテーブルを作ります。
以下のSQLは、MySQL4.1以上でOKです。(MySQL5.5でOKでした。)
MySQL4.0以下だと、「CHARSET=utf8」は文法エラーになるので削ります。
[pukiwiki_page]テーブル
#code(sql){{
CREATE TABLE IF NOT EXISTS `pukiwiki_page` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`page` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
}}
[pukiwiki_access]テーブル
#code(sql){{
CREATE TABLE IF NOT EXISTS `pukiwiki_access` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`page_id` int(11) NOT NULL,
`ip` varchar(32) NOT NULL,
`date` date NOT NULL,
`time` time NOT NULL,
PRIMARY KEY (`id`),
KEY `page_id_date` (`page_id`,`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
}}
**設定の編集 [#h152dbec]
解凍したフォルダ「lib」の中にある「_db_counter.php」で、設定を編集します。
#code(php){{
//-----------------------------------------------
// config
//-----------------------------------------------
// DB
define('DB_USER', 'mysql_username');
define('DB_PASS', 'mysql_password');
define('DB_HOST', 'localhost');
define('DB_NAME', 'mysql_dbname');
define('DB_CHAR', 'UTF-8');
define('TBL_PAGE', 'pukiwiki_page');
define('TBL_ACCESS', 'pukiwiki_access');
// URL
define('DOMAIN', 'www.mydomain.com');
define('SCRIPT', '/pukiwiki/index.php');
// ranking
define('TERM', 10); // 集計期間(日)
define('NUM', 10); // 順位数(例:10位までなら10)
}}
以下の内容を設定してください。
| 設定項目 | 内容 |h
| DB_USER | MySQLを利用するユーザー名 |
| DB_PASS | MySQLを利用するパスワード |
| DB_HOST | MySQLのホスト名(通常は「localhost」)|
| DB_NAME | MySQLのデータベース名 |
| DB_CHAR | MySQLの文字コード(通常は「UTF-8」)|
| TBL_PAGE | pukiwikiのページ名を保存するテーブル名(通常は「pukiwiki_page」)|
| TBL_ACCESS | pukiwikiのアクセスログを保存するテーブル名(通常は「pukiwiki_access」)|
| DOMAIN | pukiwikiが設置してあるWebサイトのドメイン名 |
| SCRIPT | pukiwikiのスクリプトまでのパス |
| TERM | アクセスカウンターで表示する集計期間の日数 |
| NUM | アクセスカウンターで表示する順位数(例:上位10位までなら10)|
**アクセスカウンター [#e928183e]
「skin/pukiwiki.skin.php」にアクセスカウンターを呼び出すコードを追記します。
#code(php){{
<?php
require_once('lib/_db_counter.php');
?>
}}
通常は、メニューバーの表示部分の下部に追記すればOKです。
#code(php){{
<div id="menubar">
<?php
if (arg_check('read') && exist_plugin_convert('menu')) {
echo do_plugin_convert('menu');
require_once('lib/_db_counter.php'); // アクセスカウンター
}
?>
</div>
}}
**ファイルの配置 [#yadff898]
アクセスカウンター用のフォルダとファイルを、Webサーバー内のpukiwikiを設置したディレクトリにアップロードします。
/pukiwiki/image/counter
/pukiwki/lib/_db_counter.php
/pukiwiki/skin/pukiwki.skin.php
の3つをアップロードします。
* 設置見本 [#y7896f76]
アクセスカウンターを設置すると、メニューバーの下部に以下のようなカウンターが表示されます。
&ref(pukiwiki_db_counter.png);
*ソースコード [#j56c6894]
#code(php){{
<?php
// @date 2008/12/14
// @charactor UTF-8N
// @description MySQLを使ったpukiwiki用のアクセスカウンター PHP+MySQL
/*
### MySQL table ###
[pukiwiki_page] pukiwikiのページ名(文字列)をページID(数値)に変換して利用
id INT auto_increment
page TEXT
[pukiwiki_access] アクセスログのテーブル ページID、IPアドレスを保存
id INT auto_increment
page_id INT index
ip VARCHAR(32)
date date index
time time
*/
//-----------------------------------------------
// config
//-----------------------------------------------
// DB
define('DB_USER', 'mysql_username');
define('DB_PASS', 'mysql_password');
define('DB_HOST', 'localhost');
define('DB_NAME', 'mysql_dbname');
define('DB_CHAR', 'UTF-8');
define('TBL_PAGE', 'pukiwiki_page');
define('TBL_ACCESS', 'pukiwiki_access');
// URL
define('DOMAIN', 'www.mydomain.com');
define('SCRIPT', '/pukiwiki/index.php');
// ranking
define('TERM', 10); // 集計期間(日)
define('NUM', 10); // 順位数(例:10位までなら10)
//-----------------------------------------------
//接頭辞「a_」=「access」の意
$cmd = $_GET['cmd']; // pukiwikiの処理モード
$a_page = mb_convert_encoding($_GET['page'], DB_CHAR); // pukiwikiページ名
$a_addr = $_SERVER["REMOTE_ADDR"]; // IPアドレス
$a_date = date('Y-m-d');
$a_time = date('H:i:s');
if (0 < strlen($a_page) && $cmd = 'read') {
$conn = db_open(DB_USER, DB_PASS, DB_HOST, DB_NAME);
//ページ名をページIDに変換
$page_id = db_get_page_id($conn, $a_page);
//wiki_accessに追加
db_set_access($conn, $page_id, $a_addr, $a_date, $a_time);
//カウンター値の取得
$cnt_total = db_get_total($conn);
$cnt_page = db_get_page($conn, $page_id);
$cnt_today = db_get_today($conn, $page_id, $a_date);
$cnt_yesterday = db_get_yesterday($conn, $page_id, $a_date);
//-----------------------------------------------
//ランキング表示
//-----------------------------------------------
$date_to = $a_date;
$date_from = date_from($date_to, TERM);
$rank = db_get_rank($conn, $a_date, TERM, NUM);
if (0 < count($rank)) {
echo "<h5>人気の".NUM."件</h5>\n";
//集計期間
echo "<div align='right'><span class='counter'>
(".$date_from." - ".$date_to." / ".TERM."days)</span></div><br>\n";
echo "<div>\n";
echo "<ul>\n";
foreach($rank as $page_id => $cnt) {
$page_name = db_get_page_name($conn, $page_id);
echo "<li><a href='http://".DOMAIN.SCRIPT."?".rawurlencode($page_name)."'>"
.$page_name."<span class='counter'>(".$cnt.")</span></a></li>\n";
}
echo "</ul>\n";
echo "</div>\n";
echo "<hr>\n";
}
//-----------------------------------------------
//カウンターの表示
//-----------------------------------------------
//-----------------------------------------------
//テキスト 横長表示
//-----------------------------------------------
/*
echo "<div align='right'>";
echo "WIKI : " . $cnt_total . " - ";
echo "PAGE : " . $cnt_page . " - ";
echo "TODAY : " . $cnt_today . " - ";
echo "YESTERDAY : " . $cnt_yesterday;
echo "</div>";
*/
//-----------------------------------------------
//テキスト 縦長表示
//-----------------------------------------------
/*
echo "WIKI : " . $cnt_total . "<br>";
echo "PAGE : " . $cnt_page . "<br>";
echo "TODAY : " . $cnt_today . "<br>";
echo "YESTERDAY : " . $cnt_yesterday . "<br>";
*/
//-----------------------------------------------
//画像 縦長表示
//-----------------------------------------------
$digit = strlen($cnt_total); // 桁数
$cnt_page = zero_add($cnt_page, $digit);
$cnt_today = zero_add($cnt_today, $digit);
$cnt_yesterday = zero_add($cnt_yesterday, $digit);
echo "\n<!--access counter-->\n";
echo "<table border=0 cellpadding=0 cellspacing=0>\n";
echo "<tr> <td align='left'><img src='image/counter/wiki.png'></td>
<td align='right'>".rep_num($cnt_total)."</td> </tr>\n";
echo "<tr> <td align='left'><img src='image/counter/page.png'></td>
<td align='right'>".rep_num($cnt_page)."</td> </tr>\n";
echo "<tr> <td align='left'><img src='image/counter/today.png'></td>
<td align='right'>".rep_num($cnt_today)."</td> </tr>\n";
echo "<tr> <td align='left'><img src='image/counter/yesterday.png'></td>
<td align='right'>".rep_num($cnt_yesterday)."</td> </tr>\n";
echo "</table>\n";
echo "\n<!--access counter-->\n";
db_close($conn);
}
//-----------------------------------------------
// function
//-----------------------------------------------
function db_open($mysql_user = '', $mysql_pass = '', $mysql_host = '', $mysql_db = '')
{
$conn = mysql_pconnect($mysql_host, $mysql_user, $mysql_pass);
mysql_select_db($mysql_db, $conn);
return $conn;
}
function db_close($conn)
{
return mysql_close($conn);
}
//MySQLプリペアードステートメント関数(SQLインジェクション対策)
//(参考)http://www.php.net/manual/ja/function.mysql-query.php#70686
function mysql_prepare($query, $phs = array()) {
$phs = array_map(create_function('$ph', 'return "\'".mysql_real_escape_string($ph)."\'";'), $phs);
$curpos = 0;
$curph = count($phs)-1;
for ($i = strlen($query) - 1; $i > 0; $i--) {
if ($query[$i] !== '?') {
continue;
}
if ($curph < 0 || !isset($phs[$curph])) {
$query = substr_replace($query, 'NULL', $i, 1);
} else {
$query = substr_replace($query, $phs[$curph], $i, 1);
}
$curph--;
}
unset($curpos, $curph, $phs);
return $query;
}
//ページ名をページIDにひも付け
function db_get_page_id($conn, $a_page = '')
{
$page_id = 0;
if (0 < strlen($a_page)){
//既存値のdb検索
$sql = "SELECT id FROM ".TBL_PAGE." WHERE page = ? LIMIT 1";
$param = array($a_page);
$query = mysql_prepare($sql, $param);
$rst = mysql_query($query);
if ($rst) {
//page_idがあれば返す
$row = mysql_fetch_row($rst);
if (0 < count($row)) {
$page_id = $row[0];
}
}
//page_idがなければ、新規追加してpage_idを返す
if ($page_id == 0) {
$sql = "INSERT INTO ".TBL_PAGE." (page) VALUES (?)";
$param = array($a_page);
$query = mysql_prepare($sql, $param);
mysql_query($query);
$page_id = mysql_insert_id();
}
}
return $page_id;
}
//ページIDからページ名を取得
function db_get_page_name($conn, $page_id = '')
{
$page_name = '';
if (0 < $page_id){
//既存値のdb検索
$sql = "SELECT page FROM ".TBL_PAGE." WHERE id = ? LIMIT 1";
$param = array($page_id);
$query = mysql_prepare($sql, $param);
$rst = mysql_query($query);
if ($rst) {
//page_idがあれば返す
$row = mysql_fetch_row($rst);
if (0 < count($row)) {
$page_name = $row[0];
}
}
}
return $page_name;
}
//アクセスログの記録
function db_set_access($conn, $page_id, $a_addr, $a_date, $a_time)
{
// ToDo: INSERT IGNORE INTO に置き換える
//重複チェック
$cnt = 0;
$sql = "SELECT count(*) FROM ".TBL_ACCESS." WHERE page_id = ? AND ip = ? AND date = ?";
$param = array($page_id, $a_addr, $a_date);
$query = mysql_prepare($sql, $param);
$rst = mysql_query($query);
if ($rst) {
$row = mysql_fetch_row($rst);
if (0 < count($row)) {
$cnt = $row[0];
}
}
//新規追加
if ($cnt == 0) {
$sql = "INSERT INTO ".TBL_ACCESS." (page_id, ip, date, time) VALUES (?, ?, ?, ?)";
$param = array($page_id, $a_addr, $a_date, $a_time);
$query = mysql_prepare($sql, $param);
mysql_query($query);
}
}
//全体のアクセス数
function db_get_total($conn)
{
$cnt = 0;
$sql = "SELECT count(*) FROM ".TBL_ACCESS;
$rst = mysql_query($sql);
if ($rst) {
$row = mysql_fetch_row($rst);
if (0 < count($row)) {
$cnt = $row[0];
}
}
return $cnt;
}
//ページのアクセス数
function db_get_page($conn, $page_id)
{
$cnt = 0;
$sql = "SELECT count(*) FROM ".TBL_ACCESS." WHERE page_id = ?";
$param = array($page_id);
$query = mysql_prepare($sql, $param);
$rst = mysql_query($query);
if ($rst) {
$row = mysql_fetch_row($rst);
if (0 < count($row)) {
$cnt = $row[0];
}
}
return $cnt;
}
//ページの本日のアクセス数
function db_get_today($conn, $page_id, $a_date)
{
$cnt = 0;
$sql = "SELECT count(*) FROM ".TBL_ACCESS." WHERE page_id = ? AND date = ?";
$param = array($page_id, $a_date);
$query = mysql_prepare($sql, $param);
$rst = mysql_query($query);
if ($rst) {
$row = mysql_fetch_row($rst);
if (0 < count($row)) {
$cnt = $row[0];
}
}
return $cnt;
}
//ページの昨日のアクセス数
function db_get_yesterday($conn, $page_id, $a_date)
{
$yesterday = date('Y-m-d', (strtotime($a_date) - (1 * 24 * 60 * 60)));
$cnt = 0;
$sql = "SELECT count(*) FROM ".TBL_ACCESS." WHERE page_id = ? AND date = ?";
$param = array($page_id, $yesterday);
$query = mysql_prepare($sql, $param);
$rst = mysql_query($query);
if ($rst) {
$row = mysql_fetch_row($rst);
if (0 < count($row)) {
$cnt = $row[0];
}
}
return $cnt;
}
//カウンター用数字画像の表示
function rep_num($num)
{
$str = '';
for($i = 0; $i < strlen($num); $i++)
{
$num_i = substr($num, $i, 1);
$str = $str . "<img src='image/counter/" . $num_i . ".png'>";
}
return $str;
}
//ゼロ詰め処理
function zero_add($num, $digit)
{
$format = '%0'.$digit.'d'; // 「%04d」=4桁の整数
$str = sprintf($format, $num);
return $str;
}
//アクセスランキングのデータ取得
function db_get_rank($conn, $a_date = '', $term = '', $num = 1)
{
$rank = array();
//集計開始日の指定 $a_date がある場合
if ($a_date) {
$date_from = $a_date;
$date_to = $a_date;
}
//集計開始日の指定 $a_date がない場合
else {
$date_from = date('Y-m-d');
$date_to = date('Y-m-d');
}
//集計期間の指定がある場合
if (0 < (int) $term) {
$date_from = date_from($date_to, $term);
}
$rank = array();
$sql = "SELECT page_id, count(*) AS cnt FROM ".TBL_ACCESS
." WHERE ? <= date AND date <= ? GROUP BY page_id ORDER BY cnt DESC LIMIT ".$num;
$param = array($date_from, $date_to);
$query = mysql_prepare($sql, $param);
$rst = mysql_query($query);
if ($rst) {
while ($row = mysql_fetch_assoc($rst)) {
$page_id = $row["page_id"];
$cnt = $row["cnt"];
$rank[$page_id] = $cnt;
}
}
return $rank;
}
//ランキング集計開始日の取得
function date_from($date, $term)
{
$date_from = date('Y-m-d', (strtotime($date) - ((1 * 24 * 60 * 60) * (int) ($term - 1))));
return $date_from;
}
?>
}}
*改造 [#icc3681f]
表示部分の画像や位置を、お好みに応じて変えてみてご利用ください。