トップページへ戻る

PHPへの扉
- Gateway to PHP -

@PHP.ring Home
<5 <1 Random List 1> 5>
概要
このページは個人的に作ったPHPのコードを開示しているページです。あんまり更新頻度はよくないと思いますが、こういった方面に興味があればお使いください。
Languages
Links PHP関係のリンク
レッツPHP!
画像BBSが公開されているホームページ
PHP
PHPの本家。search forに関数名を突っ込むと関数仕様がでてきます。ヘルプには非常に重宝。
PostgreSQL
PHPと親和性のいいRDB「PostgreSQL」です。
PHPの日本のユーザ会
メーリングリストに登録しとくと有益な情報があるかも。
PHP
PHP研究所。といっても、PHP Hypertext Processorではなくて、Peaceand Happiness through Prosperityのほうですが。出版社ですね。ビジネス書籍ではお世話になります。
Sitemap サイトマップ
GPSについて
GPS使った軌跡ログのとり方やforetrex 101の使用記などGPSに関する話題を公開しているページです。
淀川サイクリングについて
うちの子と淀川河川敷サイクリングの記録のページです。foretrexでルート記録とりはじめました。
PHPについて
趣味で作っているPHPスクリプトを公開しているページです。Exif,GPS絡みのPHPスクリプトを公開しています。
PCについて
HP Pavilion DV6100/CTやおうちサーバなどPC全般に関しての話題を公開しているページです。
ブログ
GPSへの扉のブログです。GPS・サイクリング・お手製ソフトの話を中心につれづれなるままにつらつらと。。。
SUPPORT掲示板
公開しているソフトの不具合や要望などはこちらにどうぞ。
旧ブログ
〜2006年までのブログ
E-Mail

メールを返す保証は全くありませんが、連絡先は上記のとおりです。
 Preanalog
Analogを使ったアクセスログの解析というのでひっかかるのが、検索式の文字化けです。Googleで「analog 検索 文字化け」あたりで検索をかけてみると、いろいろと引っかかるのですが、perlを使ったものばかりで、PHPで組まれたものは見つけられませんでした。ないものはしょうがないので検索式で文字化けしないようにくんでみました。
● PHPのコード

<?php 
// 設定始まり
// コンバート後のエンコーディングを指定 ("Shift-JIS", "EUC-JP", ...)
$encoding="UTF-8"; 
// 元のapache logのありか
$filenamer="c:\\...\\access.log";
// 変換後のapache logのありか
$filenamew="c:\\...\\access-utf8.log";
// 無視したいホスト
$ignore="hogehoge.ne.jp"; 
// 設定終わり

// ファイルオープン
$fr=fopen($filenamer,"r");
$fw=fopen($filenamew,"w");
while (!feof ($fr)) {
   $buffer  = fgets($fr, 4096);
	// はずしときたいホストはとばす
   if (strstr($buffer, $ignore)) continue;
    // URLDECODEする
   $buffer2 = urldecode($buffer);
    // 文字エンコーディングを統一する
   $buffer  = mb_convert_encoding($buffer2,$encoding,"auto");
	// 全角の空白を+に置き換える。
   $buffer2 = str_replace(mb_convert_encoding(" ",$encoding,"auto"),"+", $buffer);
    // 全角の英数字を半角にする。半角のカナを全角にする
   $buffer  = mb_convert_kana($buffer2, "KVas", $encoding);
	// googleの検索文字列は小文字に統一する
	if (strstr($buffer, "google")){
		$querytop=strstr($buffer, "q=");
		$query=substr($querytop,2, strpos($querytop,"&")-2);
		$buffer2=str_replace($query, strtolower($query),$buffer);
		$buffer=$buffer2;
	}
	// yahooの検索文字列は小文字に統一する
	if (strstr($buffer, "search.yahoo.co.jp")){
		$querytop=strstr($buffer, "p=");
		$query=substr($querytop,2, strpos($querytop,"&")-2);
		$buffer2=str_replace($query, strtolower($query),$buffer);
		$buffer=$buffer2;
	}
	// 書き出す。
   fwrite($fw, $buffer);
}
fclose($fr);
fclose($fw);
?>

● バッチファイル
上のphpを実行するために下記のバッチファイルを準備しています。
del "c:\...\access-utf8.log"
php.exe "c:\...\convert2utf.php"
c:\...\analog.exe
このバッチファイルをtaskで定期実行しています。

● 結果
結果はこんな感じです。
英数字が大文字・小文字の区別なく出せて、漢字の文字化けもなくなりました。

 


「2007.01.10 追記」
・ログが70万行近くなってきて処理速度がかなりかかるようになってきたので簡易ログ吐きもかねてC#で書き換えてしまいました。
まだ未解決なのは、mb_convert_kana()の代替処理。結構便利な関数なんだよなぁ。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Convert2Utf
{
    class Program
    {
        static private void SplitApacheLog(string line, ref string[] str)
        {
            int n = 0;
            int l = 0;
            char[] s ={ ' ', '[', ']', '"' };

            // snt2-p213.tcom.hi-ho.ne.jp - - [04/Apr/2006:00:04:13 +0900] "GET /title.jpg HTTP/1.1" 200 15030 "http://plaza.rakuten.co.jp/zzzzzzzzzzzzzz" "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; .NET CLR 1.1.4322)" 
            // Host
            if ((l = line.IndexOf(s[0], n)) < 0) return;
            str[0] = line.Substring(n, l - n);
            n = l + 1;

            // L
            if ((l = line.IndexOf(s[0], n)) < 0) return;
            str[1] = line.Substring(n, l - n);
            n = l + 1;

            // User
            if ((l = line.IndexOf(s[0], n)) < 0) return;
            str[2] = line.Substring(n, l - n);
            n = l + 2;

            // Date
            if ((l = line.IndexOf(s[2], n)) < 0) return;
            str[3] = line.Substring(n, l - n);
            n = l + 3;

            // Request
            if ((l = line.IndexOf(s[3], n)) < 0) return;
            str[4] = line.Substring(n, l - n);
            n = l + 2;

            // Response
            if ((l = line.IndexOf(s[0], n)) < 0) return;
            str[5] = line.Substring(n, l - n);
            n = l + 1;

            // Size
            if ((l = line.IndexOf(s[0], n)) < 0) return;
            str[6] = line.Substring(n, l - n);
            n = l + 2;

            // Referer
            if ((l = line.IndexOf(s[3], n)) < 0) return;
            str[7] = line.Substring(n, l - n);
            n = l + 3;

            // Clinet
            if ((l = line.IndexOf(s[3], n)) < 0) return;
            str[8] = line.Substring(n, l - n);
        }


        static void Main(string[] args)
        {
            Encoding enc = Encoding.UTF8; // コンバート後のエンコーディングを指定 ("Shift-JIS", "EUC-JP", ...)
            string filenamer = "c:\\access.log";
            string filenamew = "c:\\access-utf8.log";
            string filenamehtml = "c:\\alanac.htm";
            string buffer = "";
            DateTime targetday = DateTime.Today;
            using (StreamReader sr = new StreamReader(filenamer, Encoding.ASCII))
            {
                using (StreamWriter sw = new StreamWriter(filenamew, false, Encoding.UTF8))
                {
                    using (StreamWriter sw2 = new StreamWriter(filenamehtml, false, Encoding.UTF8))
                    {
                        // html 初期化
                        sw2.WriteLine("<html><head><title>today and yesterday</title></head><body><small><a href=\"#today\">Today</a>|<a href=\"#hits\">Hits</a>|<a href=\"#referer\">referer</a><hr/>");
                        int[] m = new int[15];
                        string[] str = new string[10];
                        string strtemp;
                        ArrayList refererlist = new ArrayList();
                        string prevhosts = "";
                        TimeSpan t;
                        bool bToday = false;
                        DateTime dtStart = DateTime.Now;


                        int i = 0;
                        while ((buffer = sr.ReadLine()) != null)
                        {
                            i++;
                            if (i % 10000 == 0)
                            {
                                System.Console.WriteLine(i.ToString() + "lines");
                            }
                            string buffer2;
                            if (buffer.Contains("euc-jp"))
                            {
                                buffer2 = System.Web.HttpUtility.UrlDecode(buffer, Encoding.GetEncoding("EUC-JP")); // urldecodeを実施
                            }
                            else if (buffer.Contains("sjis") || buffer.Contains("shift-jis") || buffer.Contains("shift_jis"))
                            {
                                buffer2 = System.Web.HttpUtility.UrlDecode(buffer, Encoding.GetEncoding("shift_jis")); // urldecodeを実施
                            }
                            else if (buffer.Contains("UTF-8"))
                            {
                                buffer2 = System.Web.HttpUtility.UrlDecode(buffer, Encoding.UTF8);
                            }
                            else if (buffer.Contains("yahoo."))
                            {
                                if (buffer.Contains("video-search."))
                                {
                                    buffer2 = System.Web.HttpUtility.UrlDecode(buffer, Encoding.UTF8);
                                }
                                else
                                {
                                    buffer2 = System.Web.HttpUtility.UrlDecode(buffer, Encoding.GetEncoding("EUC-JP"));
                                }
                            }
                            else
                            {
                                buffer2 = System.Web.HttpUtility.UrlDecode(buffer, Encoding.UTF8);
                            }
                            buffer2 = buffer2.Replace(' ', '+'); // 全角の空白を+に置換
                            if (buffer2.Contains("google"))
                            {
                                int nBufferTop = buffer2.IndexOf("q=");
                                if (nBufferTop > 0)
                                {
                                    int nBufferEnd = buffer2.IndexOf('&', nBufferTop);
                                    if (nBufferEnd < 0) nBufferEnd = buffer2.Length;
                                    string query = buffer2.Substring(nBufferTop + 2, nBufferEnd - nBufferTop - 2);
                                    buffer2 = buffer2.Remove(nBufferTop + 2, nBufferEnd - nBufferTop - 2).Insert(nBufferTop + 2, query.ToLower().Replace("\"",""));
                                }
                            }
                            if (buffer2.Contains("search.yahoo.co.jp"))
                            {
                                int nBufferTop = buffer2.IndexOf("p=");
                                if (nBufferTop > 0)
                                {
                                    int nBufferEnd = buffer2.IndexOf('&', nBufferTop);
                                    if (nBufferEnd < 0) nBufferEnd = buffer2.Length;
                                    string query = buffer2.Substring(nBufferTop + 2, nBufferEnd - nBufferTop - 2);
                                    buffer2 = buffer2.Remove(nBufferTop + 2, nBufferEnd - nBufferTop - 2).Insert(nBufferTop + 2, query.ToLower().Replace("\"", ""));
                                }
                            }
                            sw.WriteLine(buffer2);

                            // html向け解析
                            SplitApacheLog(buffer2, ref str);
                            DateTime d = DateTime.ParseExact(str[3].Substring(0, 20),
                                                    "dd/MMM/yyyy':'HH':'mm':'ss",
                                                    System.Globalization.DateTimeFormatInfo.InvariantInfo,
                                                    System.Globalization.DateTimeStyles.None);
                            if (d.Date == targetday || d.Date == targetday.AddDays(-1.0))
                            {
                                if (d.Date == targetday && !bToday)
                                {
                                    bToday = true;
                                    sw2.WriteLine("<hr /><font color=\"blue\"><b id=\"today\">Today</b></font><hr />");
                                }
                                if (prevhosts != str[0])
                                {
                                    sw2.WriteLine("<hr />");
                                }
                                if (str[7] != "-")
                                {
                                    buffer2 = buffer2.Replace(str[7], "<a href=\"" + str[7] + "\">" + str[7] + "</a>");
                                }
                                sw2.WriteLine(buffer2 + "<br />");
                                strtemp = str[7].ToLower();
                                if (strtemp.IndexOf("etoh.minidns.net") < 0 && strtemp != "" && strtemp != "-")
                                {
                                    refererlist.Add(str[7]);
                                }
                            }
                            prevhosts = str[0];
                            if (d.Date >= targetday.Subtract(new TimeSpan(14, 0, 0, 0, 0)) && d.Date <= targetday)
                            {
                                t = d.Date - targetday.Subtract(new TimeSpan(14, 0, 0, 0, 0));
                                m[t.Days]++;
                            }
                        }// while
                        sw2.WriteLine("<hr id=\"hits\" />");
                        for (int j= 14; j >= 0; j--)
                        {
                            sw2.WriteLine(
                                string.Format("{0} : {1} Hits<br />", targetday.Subtract(new TimeSpan(14 - j, 0, 0, 0)).ToShortDateString(), m[j]));
                        }
                        sw2.WriteLine("<hr id=\"referer\" />");
                        string strPrevReferer = "";
                        refererlist.Sort();
                        string strUrlReferer;
                        foreach (string strReferer in refererlist)
                        {
                            if (strPrevReferer != strReferer && strReferer != "-")
                            {
                                strUrlReferer = "<a href=\"" + strReferer + "\">" + strReferer + "</a>";
                                sw2.WriteLine(strUrlReferer + "<br />");
                            }
                            strPrevReferer = strReferer;
                        }

                        DateTime dtEnd = DateTime.Now;
                        TimeSpan ts = dtEnd - dtStart;
                        sw2.WriteLine(string.Format("{0}秒 [{1}]", ts.TotalMilliseconds / 1000.0, dtEnd.ToShortTimeString()));
                        sw2.WriteLine("</small></body></html>");
                    }
                }
            }
        }
    }
}
Google

©2004-2005 et's PHP page

counter