人気記事ランキングを設置(再び)

  • 投稿日:
  • by

以前、
「Project MultiBurst:EUCでの人気記事ランキング」

というのをやりましたが、このランキングだとある一定期間のランキングが表示できませんでした。

そこで、
「Project MultiBurst:データベースをPostgreSQLからMySQLへ移行」
でMySQLに移行してアクセスランキングを設置していたのですが、このアクセスランキングだと、ページを表示するたびに、MySQLに接続、Insertをするものだから、ページ表示が重い、という難点がありました。


で、いろいろググっていたら、私の望んでいるもの、そのままズバリのものがありました。


人気記事のランキングを表示する - Open MagicVox.net


これを設置したので、うちのサーバーの環境でのやり方を含めて紹介します。

まず、上記記事から、「hottopic200.php.tmpl」というファイルをダウンロードします。


このファイルをテキストエディタ等で開きます。

そして、MTの新規インデックス・テンプレートを作成し、先ほどのファイルの中身をそのままコピペして保存します。(再構築はまだよ)

・テンプレート名・・・・「人気記事ランキング解析用テンプレ」(名前は何でも可)
・出力ファイル名・・・・「php-ranking.php」(これも何でも可)


このテンプレートの中身は、そのままだとおそらく動かないので、
自分のサーバーの環境に合わせて設定を変更します。


まず、

// 過去 n 日間のログを集計する
$nDivDay = 2;

// 上位 n 件を集計する
$nTopEntry = 20;

この二つに関してはお好みで。


// ログファイルのディレクトリパス
$szLogDir = '/home2/apache-logs';


ここは、Apache等のWEBサーバがログをはき出すディレクトリをしています。

// 集計結果の出力ファイルパス
$szOutput = '<$MTCGIServerPath$>/blogs/project-multiburst/hottopic.php';


ここでは、「アクセス解析結果が書き出されるファイルをどこに置くか」を指定します。

これは最終的には、PHPのモジュールとしてインクルードしたいので、
その場所へファイルを出力するように設定します。

具体的に書くと、メインページで、

<!-- ランキング ここから -->
<div class="sidetitle">
最近の注目記事
</div>
<div class="side">
<div id="hottopic">
<? include("<$MTBlogURL$>hottopic.php"); ?>
</div>
</div>
<!-- ランキング ここまで -->

という感じでPHPモジュールをインクルードしたいので、それにあわせて、

// 集計結果の出力ファイルパス
$szOutput = '<$MTCGIServerPath$>/blogs/project-multiburst/hottopic.php';

としました。

「サーバーでのパス」と「テンプレートで呼び出すURL」を合わせる感じですかね。。(^^;)

続いて、アクセス・ログファイルを解析する設定の部分です。

////////////////////////////////////////////////////////////////////////
// 集計するログファイル名の配列を返す
/*array*/ function GetLogFileNames ()
{
global $nDivDay, $nCurTime;

$ret = array ();
// 毎日、別ファイルにログが作られる @ SAKURA Internet

// for (/*過去n日*/ $past = 0; $past <= $nDivDay; $past++)
for (/*過去n日*/ $past = 0; $past <= 1; $past++)
{
$t = localtime ($nCurTime - $past * 86400);
/*年*/ $year = $t[5] + 1900;
/*月*/ $month = $t[4] + 1;
/*日*/ $day = $t[3];

// サーバによってログファイル名が異なると思いますので
// ご使用の環境に合わせてコードを適宜修正してください m(_ _)m
// 存在しないファイルは無視しますので、とりあえず何パターンか書いておきます。
array_push ($ret, sprintf ("access_log.%d", $past));
// array_push ($ret, sprintf ("access_log_%04d%02d%02d", $year, $month, $day));
// array_push ($ret, sprintf ("access_log_%04d%02d%02d.gz", $year, $month, $day));
}
array_push ($ret, sprintf ("access_log"));

return ($ret);
}


赤文字の部分をコメントアウトし、青文字のように変更しています。


うちのサーバー(Apache)では、ログのローテーションをしており、Apacheのログは、

access_log

access_log.1

access_log.2

access_log.3

access_log.4

1週間毎に、4世代残しように設定しています。

ですので過去2日間のランキングを表示するので必要なログファイルは、最低でも、「access_log」と「access_log.1」です。

ということで、

for ($past = 0; $past &lt;= 1; $past++)

のように、設定しています。


次に実際のランキング出力の部分の設定です。

CSS用にいろいろclassを付けてもよかったのですが、後からの自由度を考え、シンプルにしました。


/******** エントリ1つの成形 ********/ $ret = <<<MYHTMLSAFEOUTPUT
<li><a title="{$entry['EntryTitle']}" href="{$entry['EntryPermalink']}">{$entry['EntryTitle']}</a> ({$entry['ReferCount']}hits)
</li>

MYHTMLSAFEOUTPUT;
/******** エントリ1つの成形 ********/

 ・
 ・
 ・

/******** ページ全体の成形 ********/ $ret = <<<MYHTMLSAFEOUTPUT
<ol>
{$entry_list}
</ol>
&nbsp;

MYHTMLSAFEOUTPUT;
/******** ページ全体の成形 ********/


実際に出力される形式は、

<ol>
<li><a title="エントリータイトル" href="エントリーへのリンク">エントリータイトル</a> (ヒット件数)</li>
<li><a title="エントリータイトル" href="エントリーへのリンク">エントリータイトル</a> (ヒット件数)</li>
<li><a title="エントリータイトル" href="エントリーへのリンク">エントリータイトル</a> (ヒット件数)</li>
</ol>

となります。


これで設定がすべて終わったので、このインデックステンプレートをリビルドします。

そして、このリビルドしてできあがった「php-ranking.php」は、集計用のPHPの実行スクリプトそのものになります


このPHPスクリプトを定期的にcronで実行するように設定します。

15 * * * * /usr/bin/php /(上記PHPへのパス)/php-ranking.php


というふうに、1時間に1回更新するように設定しました。


実行結果は常に「hottopic.php」というファイルに出力されるので、これをメインページ等にPHPファイルとしてインクルードします。

下記のようになります。


<!-- 注目記事ランキング ここから -->
<div class="sidetitle">
最近の注目記事
</div>
<div class="hottopic">
<? include("<$MTBlogURL$>hottopic.php"); ?>
</div>
<!-- 注目記事ランキング ここまで -->


トップページの左サイドバーに設置しました。

rankingdesu.gif

参考になれば幸いです(^^;)