<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>何もない場所 &#187; PHP</title>
	<atom:link href="http://blog.chisyamori.com/kay/category/web/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.chisyamori.com/kay</link>
	<description>──あなたの心の琴線に触れるようなものは何もないです。かといって、他の何があるわけでもないですが。</description>
	<lastBuildDate>Mon, 23 Aug 2010 13:34:12 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>パーマリンクのリダイレクト</title>
		<link>http://blog.chisyamori.com/kay/2007/06/04/105/</link>
		<comments>http://blog.chisyamori.com/kay/2007/06/04/105/#comments</comments>
		<pubDate>Sun, 03 Jun 2007 23:36:56 +0000</pubDate>
		<dc:creator>KAY</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[WEB制作]]></category>
		<category><![CDATA[ムーバブルタイプ]]></category>
		<category><![CDATA[ワードプレス]]></category>

		<guid isPermaLink="false">http://blog.chisyamori.com/kay/2007/06/04/105/</guid>
		<description><![CDATA[ブログをMovable TypeからWordPressに移行する際、記事やコメントに関してはWordPress側でコンバートツールが実装されてるので特に問題は無いのですが、URIが変わってしまうという点が一番ネックになる [...]]]></description>
			<content:encoded><![CDATA[<p>ブログをMovable TypeからWordPressに移行する際、記事やコメントに関してはWordPress側でコンバートツールが実装されてるので特に問題は無いのですが、URIが変わってしまうという点が一番ネックになると思います。<br />
KAYも最初は、引っ越しメッセージ付きのRSSだけ用意しといて後は諦めるか、と思ってたんですが、記事数もそんなに多くないし（ちょうど100件だった）、せっかくだから全記事リダイレクトしたれと思ってこんなスクリプトを書いてみました。<br />
<span id="more-105"></span></p>
<pre>&lt;?php
require_once("MDB2.php");  

$db =&amp; MDB2::factory("mysql://user:pass@host/dbname");

$sql = &lt;&lt;&lt;SQL
select
date_format(mt_entry.entry_created_on, '%Y/%m/'),
mt_entry.entry_basename,
date_format(mt_entry.entry_created_on, '%Y/%m/%d/'),
wp_posts.id
from wp_posts
left join mt_entry on mt_entry.entry_title = wp_posts.post_title
SQL;
$result =&amp; $db-&gt;query($sql);
while($row = $result-&gt;fetchRow()) {
    echo "Redirect /blog/" . $row[0] . $row[1] . ".html http://blog.chisyamori.com/kay/" . $row[2] . $row[3] . "/\\n";
}
$db-&gt;disconnect();
?&gt;</pre>
<p>ちなみに、MT、WPの両方でMySQLを使っているという前提です。MDB2::factory()の引数はお使いのデータベースに合わせて適宜変更して下さい。<br />
まず、ムーバブルタイプのmt_entryテーブルをワードプレスのテーブルが入っているDBにあらかじめインポートしておきます。<br />
で、上記のスクリプトを適当なファイル名で保存して、PHPとして実行してやる。<br />
シェル上でならこんな感じ。</p>
<pre>$ php htaccess.php &gt; .htaccess</pre>
<p>まあ、普通にWEB上からアクセスして出力されたページをコピペして保存してもいいんですけど。<br />
joinする時に記事タイトルで結合させるのがミソですね。<br />
後は、MT側とWP側の書式に合ったパーマリンクを整形して出力してやれば、お手軽リダイレクト用.htaccessの出来上がり。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chisyamori.com/kay/2007/06/04/105/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ちょっとびっくりした。</title>
		<link>http://blog.chisyamori.com/kay/2006/12/01/70/</link>
		<comments>http://blog.chisyamori.com/kay/2006/12/01/70/#comments</comments>
		<pubDate>Fri, 01 Dec 2006 09:45:00 +0000</pubDate>
		<dc:creator>KAY</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[WEB制作]]></category>
		<category><![CDATA[お絵描き]]></category>

		<guid isPermaLink="false">http://blog.chisyamori.com/kay/?p=70</guid>
		<description><![CDATA[先日から稼動させているお絵描き掲示板ですが、なんとスパム書き込みが。
掲示板部分は完全に自作なので、ちょっとびっくりしました。
やっぱフォーム部品のname属性値は無難な名前にしとくと危険なんですかねー。
あと、スパム対 [...]]]></description>
			<content:encoded><![CDATA[<p>先日から稼動させているお絵描き掲示板ですが、なんとスパム書き込みが。<br />
掲示板部分は完全に自作なので、ちょっとびっくりしました。<br />
やっぱフォーム部品のname属性値は無難な名前にしとくと危険なんですかねー。<br />
あと、スパム対策処理も入れとかないと……。うぜー。<br />
とりあえず、あんまりめんどくさい処理は入れたくないんで、前にWikiのスパム対策でやったASCII文字のみの投稿は弾く、という線で行こうかな。</p>
<p>あと、PCH（アニメーション）の再生機能の追加と……データベースの方で、PCH再生を許可するかどうかのフラグもあった方がいいのかな。<br />
当初は、PCHが存在するかどうかで再生の可否を判別しようと思ってたんだけど。<br />
一応、投稿後にPCHダウンロードのリンクと、PCHをサーバから削除するチェックボックスはあるんだけど、上書き用にPCHは残しておいて、でも再生はさせたくない、というニーズもあると思うんだよねえ。</p>
<p>それと、新規お絵描き投稿の時のアップロード処理が無くなった関係で、ひとつ画面遷移が必要な部分が減ったので、もうちょいAjax寄りにしてもいいかなと思った。<br />
まあどうなるかわかりませんけどね……。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chisyamori.com/kay/2006/12/01/70/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>お絵描き掲示板制作進捗</title>
		<link>http://blog.chisyamori.com/kay/2006/11/28/69/</link>
		<comments>http://blog.chisyamori.com/kay/2006/11/28/69/#comments</comments>
		<pubDate>Tue, 28 Nov 2006 12:58:37 +0000</pubDate>
		<dc:creator>KAY</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[WEB制作]]></category>
		<category><![CDATA[お絵描き]]></category>

		<guid isPermaLink="false">http://blog.chisyamori.com/kay/?p=69</guid>
		<description><![CDATA[上書き機能追加～。
う～んしかし、ブラウザのキャッシュどうにかならんかなー。画像の方はまあ、どうにかすればどうとでもなりそうかなという気はするんだけど。
問題はPCH（アニメーション）ファイル。
一度PCHから上書きする [...]]]></description>
			<content:encoded><![CDATA[<p>上書き機能追加～。<br />
う～んしかし、ブラウザのキャッシュどうにかならんかなー。画像の方はまあ、どうにかすればどうとでもなりそうかなという気はするんだけど。<br />
問題はPCH（アニメーション）ファイル。<br />
一度PCHから上書きすると、それがキャッシュに残るのね。んで、その状態で再度上書きするとアプレットはキャッシュの方を参照しちゃう模様……。<br />
つかまあ、Operaでしかチェックしてないし、もしかしたらIEなんかは違う挙動すんのかもしんないけど……。<br />
同じ画像を2回以上立て続けに上書きする場合なんてそうそうないかなーとか思って、今のところ放置してます。</p>
<p>meta要素で「no-cache」とかあるけど、あれはアプレットから読み込まれるファイルにも有効なんだろうか。当該のHTMLのみか？　あとでちょっと試してみよう……。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chisyamori.com/kay/2006/11/28/69/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>もうこれでリニューアル完了っていう事でいいよ。</title>
		<link>http://blog.chisyamori.com/kay/2006/10/31/68/</link>
		<comments>http://blog.chisyamori.com/kay/2006/10/31/68/#comments</comments>
		<pubDate>Mon, 30 Oct 2006 16:45:38 +0000</pubDate>
		<dc:creator>KAY</dc:creator>
				<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WEB制作]]></category>
		<category><![CDATA[お絵描き]]></category>

		<guid isPermaLink="false">http://blog.chisyamori.com/kay/?p=68</guid>
		<description><![CDATA[結局CSSは必要最小限で。そのうち気が向いたら代替CSSとか導入するかも。
あと、しぃペインターを導入して絵板を復活させました。
一応サーバ側の処理は自分でスクリプト書いたんだけど、なんかいろいろ挫折した。
いちびってa [...]]]></description>
			<content:encoded><![CDATA[<p>結局CSSは必要最小限で。そのうち気が向いたら代替CSSとか導入するかも。</p>
<p>あと、<a href="http://shichan.jp/" rel="external">しぃペインター</a>を導入して絵板を復活させました。<br />
一応サーバ側の処理は自分でスクリプト書いたんだけど、なんかいろいろ挫折した。<br />
いちびってajax使っていろいろやってみようと思ってたんだけど、object要素があまりにも使えず……。orz<br />
ていうか、Firefox2.0でobject要素に対してtypeofしたら&#8221;function&#8221;を返すのはなぜなんだぜ？</p>
<p>ライブコネクトのコールバック関数とかもうまく動かないし、iframeの代替として使おうとしても全然思うような動作しないし……。<br />
XHTML+PHP+MySQL+Ajaxなお絵描き掲示板として華麗にデビューさせたかったんだけどなあ……。</p>
<p>とりあえず、現時点で超超作りかけです。KAYが使えればいいやという感じで作ったので、返信機能すらありません。<br />
IEにも対応してません。IE7ではどうだろう……。<br />
KAY以外の方も使っていただいて全然構いませんが、まあ誰も使わないだろな。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chisyamori.com/kay/2006/10/31/68/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>pukiwikiのスパム対策</title>
		<link>http://blog.chisyamori.com/kay/2006/05/05/44/</link>
		<comments>http://blog.chisyamori.com/kay/2006/05/05/44/#comments</comments>
		<pubDate>Fri, 05 May 2006 09:39:35 +0000</pubDate>
		<dc:creator>KAY</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[WEB制作]]></category>

		<guid isPermaLink="false">http://blog.chisyamori.com/kay/?p=44</guid>
		<description><![CDATA[最近OekakiBBS Wikiの方でスパム投稿がひどくて困ってたんですが、このほどスパム対策を施してみました。
なんか、マルチバイト文字を含まない投稿を弾くというのが結構効くらしい、という事で、trackerプラグイン [...]]]></description>
			<content:encoded><![CDATA[<p>最近<a href="http://kay.chisyamori.com/oekaki/wiki/" rel="outside">OekakiBBS Wiki</a>の方でスパム投稿がひどくて困ってたんですが、このほどスパム対策を施してみました。<br />
なんか、マルチバイト文字を含まない投稿を弾くというのが結構効くらしい、という事で、trackerプラグインを改造して実装してみる事に。<br />
trackerプラグインから投稿があった時に、以下の処理を実行します。</p>
<p><span id="more-44"></span></p>
<pre>    //KAY追加部分
    $flag = true;
    $str_tmp = $post["_name"] . $post["name"] . $post["url"] . $post["body"];
    $n = strlen($str_tmp);
    for($i = 0; $i &lt; $n; $i++) {
        if(ord(substr($str_tmp, $i, 1)) &gt;= 0x80) {
            $flag = false;
            break;
        }
    }
    if($flag) {
        return array(
            'msg'=&gt;'cannot write',
            'body'=&gt;'error.'
        );
    }
    //KAY追加部分ここまで</pre>
<p>$postというのはPOSTで渡ってきたデータらしいです。やり方としては、これで合ってるんだろうか。<br />
ちょい様子見～。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chisyamori.com/kay/2006/05/05/44/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>テンプレートクラス</title>
		<link>http://blog.chisyamori.com/kay/2006/04/30/43/</link>
		<comments>http://blog.chisyamori.com/kay/2006/04/30/43/#comments</comments>
		<pubDate>Sun, 30 Apr 2006 08:06:39 +0000</pubDate>
		<dc:creator>KAY</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[WEB制作]]></category>

		<guid isPermaLink="false">http://blog.chisyamori.com/kay/?p=43</guid>
		<description><![CDATA[簡素なPHPのテンプレートクラス。置換、ループ、ifが使えます。

class template {
    var $pieces;               //テンプレート。ファイル名か、あるいは文字列そのものを [...]]]></description>
			<content:encoded><![CDATA[<p>簡素なPHPのテンプレートクラス。置換、ループ、ifが使えます。</p>
<p><span id="more-43"></span></p>
<pre>class template {
    var $pieces;               //テンプレート。ファイル名か、あるいは文字列そのものを配列で格納する。
    var $dir;                  //テンプレートが置かれているディレクトリ
    var $assigns;              //置換文字列バッファ
    var $if;                   //ifバッファ
    var $loops;                //ループバッファ
    var $loop;                 //カレントのループ
    var $exit = true;          //flushした時点でスクリプトを終了させるかどうか。
    var $ret_str = false;      //flushした時に出力を行わず、文字列を返す場合はtrue

    //コンストラクタ
    function template($list, $dir = "./") {
        $this-&gt;pieces = $list;
        $this-&gt;dir = $dir;
        $this-&gt;assigns = array();
        $this-&gt;if = array();
        $this-&gt;loops = array();
    }

    //改行コードを統一
    function CR($str) {
        $str = str_replace("\\r\\n", "\\n", $str);
        $str = str_replace("\\r", "\\n", $str);
        return $str;
    }

    //ループの定義
    function set_loop($loop) {
        $this-&gt;loop = $loop;
        $this-&gt;loops[$loop] = array();
    }

    //割り当て
    function assign($name, $value) {
        $this-&gt;loops[$this-&gt;loop][$name][] = $value;
    }

    //出力
    function flush() {
        $html = "";

        //ファイルの読み込み
        foreach($this-&gt;pieces as $val) {
            $file = $this-&gt;dir . ((substr($this-&gt;dir, -1) == "/")? "": "/") . $val;
            if(file_exists($file)) {
                $html .= file_get_contents($file);
            } else {
                $html .= $val;
            }
        }
        $html = $this-&gt;CR($html);

        //if処理
        preg_match_all("/%if:(.+?)%/", $html, $match);
        foreach($match[1] as $val) {
            $html = preg_replace("/\\s*%if:" . $val . "%(.*?)\\s*%endif:" . $val . "%/s", (isset($this-&gt;if[$val]) &#038;&#038; $this-&gt;if[$val])? "$1": "", $html);
        }

        //ループ処理
        foreach($this-&gt;loops as $key =&gt; $val) {
            preg_match("/\\s*%loop:" . $key . "%(.*?)\\s*%next:" . $key . "%/s", $html, $matches);

            $names = array_keys($val);
            $values = array_values($val);
            array_walk($names, create_function('&#038;$names', '$names = "%" . $names . "%";'));

            $inner = "";
            $n = count(isset($values[0])? $values[0]: array());
            while($n--) {
                foreach($values as $key2 =&gt; $val2) {
                    $replace[$key2] = array_shift($values[$key2]);
                }
                $inner .= str_replace($names, $replace, $matches[1]);
            }

            $html = preg_replace("/\\s*%loop:" . $key . "%.*?\\s*%next:" . $key . "%/s", $inner, $html);
        }

        //置換処理
        foreach($this-&gt;assigns as $key =&gt; $val) {
            $html = str_replace("%" . $key . "%", $val, $html);
        }

        if($this-&gt;ret_str) { return $html; } else { echo $html; }
        if($this-&gt;exit) { exit(); }
    }
}</pre>
<p>●使い方</p>
<pre>$tmpl = new template(array("header.html", "hoge.html"), "template");</pre>
<p>でインスタンスを作成します。第一引数は配列なので、複数のファイル名を指定できます。<br />
最終的には配列の順番で各ファイルは結合されて出力されます。</p>
<pre>$tmpl-&gt;flush();</pre>
<p>でテンプレートを出力します。</p>
<pre>$tmpl-&gt;pieces[1] = "foo.html";</pre>
<p>のようにして後からテンプレートファイルを差し替える事も可能。<br />
第二引数はテンプレートファイルが置かれたディレクトリを指定します。最後の「/」はあっても無くても構いません。<br />
絶対指定でもカレントからの相対指定でも可。省略した場合はカレントのディレクトリからファイルを探します。</p>
<p>○置換</p>
<pre>※テンプレート側の記述
&lt;input type="text" name="hogege" value="%val%"&gt;

※スクリプト側の記述
$tmpl-&gt;assigns["val"] = "hogehoge";

●結果
&lt;input type="text" name="hogege" value="hogehoge"&gt;</pre>
<p>○ループ</p>
<pre>※テンプレート側の記述
&lt;ul&gt;
%loop:list%
    &lt;li&gt;%name%&lt;/li&gt;
%next:list%
&lt;/ul&gt;

※スクリプト側の記述
$arr = array("hoge", "foo", "bar");
$tmpl-&gt;set_loop("list");
foreach($arr as $val) {
    $tmpl-&gt;assign("name", $val);
}

●結果
&lt;ul&gt;
    &lt;li&gt;hoge&lt;/li&gt;
    &lt;li&gt;foo&lt;/li&gt;
    &lt;li&gt;bar&lt;/li&gt;
&lt;/ul&gt;</pre>
<p>○if</p>
<pre>※テンプレート側の記述
&lt;h1&gt;見えるかな？&lt;/h1&gt;
%if:message%&lt;p&gt;見えてますね？&lt;/p&gt;%endif:message%
&lt;p&gt;どうでしょう。&lt;/p&gt;

※スクリプト側の記述
$tmpl-&gt;if["message"] = true;

●結果
&lt;h1&gt;見えるかな？&lt;/h1&gt;
&lt;p&gt;見えてますね？&lt;/p&gt;
&lt;p&gt;どうでしょう。&lt;/p&gt;

※スクリプト側の記述
$tmpl-&gt;if["message"] = false;

●結果
&lt;h1&gt;見えるかな？&lt;/h1&gt;
&lt;p&gt;どうでしょう。&lt;/p&gt;</pre>
<p>ifはtrue以外は常に非表示となるので、表示させる時だけtrueを指定する、という感じでいいと思います。</p>
<p>デフォルトではflush()を実行した時点でスクリプトが終了してしまいます。</p>
<pre>$tmpl-&gt;exit = false;</pre>
<p>とするとflush()後もスクリプトは続行します。<br />
また、</p>
<pre>$tmpl-&gt;ret_str = true;</pre>
<p>とすると出力を行わず、結果を文字列として返します。</p>
<pre>$tmpl-&gt;ret_str = true;
$html = $tmpl-&gt;flush();</pre>
<p>でflush()の結果が$htmlに代入されます。ちなみに、ret_strがtrueの場合、exitがtrue（デフォルト）でもスクリプトは終了しません。</p>
<p>あと、CR()は改行を「\n」に置換します。便利なので何かっつーと</p>
<pre>$str = template::CR($str);</pre>
<p>みたいな感じで使ってます。</p>
<p>う～ん、説明すべき部分はこんなもんかなあ。なんか、ループを入れ子に出来るようにしようと思ったんだけど、脳が沸騰しそうになったのでやめた。<br />
あーループといえば、ほんとはこれもメソッドじゃなくて配列だけでプロパティとして扱いたかったんだよなあ……。いや、現時点の仕様でもそういう風に扱えるんだけど。<br />
あまりに多次元すぎて逆に判りにくいかなと。で、配列を意識しなくて済むようにメソッドを実装しました……。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chisyamori.com/kay/2006/04/30/43/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHPで多次元配列をソート。</title>
		<link>http://blog.chisyamori.com/kay/2006/04/23/42/</link>
		<comments>http://blog.chisyamori.com/kay/2006/04/23/42/#comments</comments>
		<pubDate>Sun, 23 Apr 2006 01:12:55 +0000</pubDate>
		<dc:creator>KAY</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.chisyamori.com/kay/?p=42</guid>
		<description><![CDATA[俺様用メモ。 $arr = array( array("0", "2"), array("2", "0"), array("2", "1"), array("1", "2"), array("0", "2"), array("1", "1"), array("0", "0"), array("0", "1"), array("2", "2"), array("1", "0") ); usort($arr, create_function('$a, $b', 'return ($a[0] < $b[0])? -1: (($a[0] == $b[0])? (($a[1] > $b[1]? -1: (($a[1] == $b[1])? 0: 1))): 1);')); print_r($arr); 結果： Array ( [0] => Array([0] => 0, [...]]]></description>
			<content:encoded><![CDATA[<p>俺様用メモ。</p>
<pre>
$arr = array(
    array("0", "2"),
    array("2", "0"),
    array("2", "1"),
    array("1", "2"),
    array("0", "2"),
    array("1", "1"),
    array("0", "0"),
    array("0", "1"),
    array("2", "2"),
    array("1", "0")
);

usort($arr, create_function('$a, $b', 'return ($a[0] < $b[0])? -1: (($a[0] == $b[0])? (($a[1] > $b[1]? -1: (($a[1] == $b[1])? 0: 1))): 1);'));
print_r($arr);
</pre>
<p>結果：</p>
<pre>
Array
(
    [0] => Array([0] => 0, [1] => 2)
    [1] => Array([0] => 0, [1] => 2)
    [2] => Array([0] => 0, [1] => 1)
    [3] => Array([0] => 0, [1] => 0)
    [4] => Array([0] => 1, [1] => 2)
    [5] => Array([0] => 1, [1] => 1)
    [6] => Array([0] => 1, [1] => 0)
    [7] => Array([0] => 2, [1] => 2)
    [8] => Array([0] => 2, [1] => 1)
    [9] => Array([0] => 2, [1] => 0)
)
</pre>
<p>こういう可読性の低いコード書いて、毎回後から後悔するんですが。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chisyamori.com/kay/2006/04/23/42/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vol.3の投票システム（その3）</title>
		<link>http://blog.chisyamori.com/kay/2006/04/03/39/</link>
		<comments>http://blog.chisyamori.com/kay/2006/04/03/39/#comments</comments>
		<pubDate>Mon, 03 Apr 2006 00:45:29 +0000</pubDate>
		<dc:creator>KAY</dc:creator>
				<category><![CDATA[Famicompo mini]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.chisyamori.com/kay/?p=39</guid>
		<description><![CDATA[やっべ。
一応マニュアルでバージョン間の仕様の差異を確認しながら書いてたんだけど、いざサーバにアップしてみたら正常に動かないとことかあるわ。
ローカルに入れてるのはwin版のPHP5なんだよなあ。
やっぱりちょくちょくう [...]]]></description>
			<content:encoded><![CDATA[<p>やっべ。<br />
一応マニュアルでバージョン間の仕様の差異を確認しながら書いてたんだけど、いざサーバにアップしてみたら正常に動かないとことかあるわ。<br />
ローカルに入れてるのはwin版のPHP5なんだよなあ。<br />
やっぱりちょくちょくうｐしつつ動作確認した方がいいね。<br />
てゆか作業遅れ気味。やばす。</p>
<p>今回は、自前でHTMLテンプレートのクラスを書いてみました。超簡単なやつ。特徴としては、複数のファイルを同時にテンプレートとして扱える点。<br />
全てのファイルが同列なので、メインのファイルからヘッダ用ファイルをインクルードして……っていうのとはちょっと違います。（まあ、そういうやり方も出来なくはないですが）<br />
イメージとしては、ぶつ切りにしたHTMLを並べて切り貼りする感じ。意外とこれ、便利です。智者森もリニューアルする時はこれ使おうかなとか思ってます。<br />
また折を見てソース公開しますね。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chisyamori.com/kay/2006/04/03/39/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vol.3の投票システム（その2）</title>
		<link>http://blog.chisyamori.com/kay/2006/03/24/38/</link>
		<comments>http://blog.chisyamori.com/kay/2006/03/24/38/#comments</comments>
		<pubDate>Fri, 24 Mar 2006 00:09:35 +0000</pubDate>
		<dc:creator>KAY</dc:creator>
				<category><![CDATA[Famicompo mini]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[雑記]]></category>

		<guid isPermaLink="false">http://blog.chisyamori.com/kay/?p=38</guid>
		<description><![CDATA[ﾊﾞﾛｽｗｗｗｗｗｗｗｗｗｗｗｗｗなんかPHPで一から書き始めてるしｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗ
↑VIP風
いや、心意気だけは「1週間で書き上げる！！！」って感じで。
defineはあんまり好きじゃないで [...]]]></description>
			<content:encoded><![CDATA[<p>ﾊﾞﾛｽｗｗｗｗｗｗｗｗｗｗｗｗｗなんかPHPで一から書き始めてるしｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗｗ<br />
↑VIP風</p>
<p>いや、心意気だけは「1週間で書き上げる！！！」って感じで。<br />
defineはあんまり好きじゃないです。shiftキーを押さなきゃいけないから。まあ、慣習的に大文字でってなってるだけで、別に小文字でもいいみたいですが。可読性の観点からも大文字の方がいいんでしょうね。<br />
かといって、define使わなかったらローカルのスコープでいちいちglobal呼ばなきゃならんのよなあ。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chisyamori.com/kay/2006/03/24/38/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>アクセス解析</title>
		<link>http://blog.chisyamori.com/kay/2006/01/06/7/</link>
		<comments>http://blog.chisyamori.com/kay/2006/01/06/7/#comments</comments>
		<pubDate>Fri, 06 Jan 2006 01:14:31 +0000</pubDate>
		<dc:creator>KAY</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[WEB制作]]></category>

		<guid isPermaLink="false">http://blog.chisyamori.com/kay/?p=7</guid>
		<description><![CDATA[智者森で使ってるアクセス解析をPHP＋データベースにしました。
それに伴って、サイトの一部が（無駄に）PHP化してます。各ディレクトリのインデックスのファイル名変えたんで、もしかしたらリンク切れとかあるかも。まあ、インデ [...]]]></description>
			<content:encoded><![CDATA[<p>智者森で使ってるアクセス解析をPHP＋データベースにしました。<br />
それに伴って、サイトの一部が（無駄に）PHP化してます。各ディレクトリのインデックスのファイル名変えたんで、もしかしたらリンク切れとかあるかも。まあ、インデックスファイルはファイル名指定せずにアンカー張るようにしてたから、多分大丈夫だと思うけど。</p>
<p>PHPとDB使ったアクセス解析は以前からやりたかったんですよねー。ようやくです。今後もちょくちょく智者森改革はやっていきたいですね。<br />
てゆか、掲示板どうしよ。ブログあったらいらないような……。</p>
<p>で、今回作ったアクセス解析ですが、いたってシンプルです。つーかアクセス解析で何が重要って、ログ取りの部分じゃなくて解析データ表示のインターフェースですよね。個人的にそこら辺、ずらずらっと生ログが表示される感じで十分なので……。</p>
<p>アクセスログ用のDBのテーブルですが、こんな感じです。</p>
<p><span id="more-7"></span></p>
<p>●生ログ記録用</p>
<pre>
CREATE TABLE access (
id int( 10 ) unsigned NOT NULL AUTO_INCREMENT ,
axs_date datetime NOT NULL default '0000-00-00 00:00:00',
lang varchar( 255 ) default NULL ,
char_set varchar( 255 ) default NULL ,
ref varchar( 255 ) default NULL ,
ua varchar( 255 ) default NULL ,
ip varchar( 255 ) default NULL ,
host varchar( 255 ) default NULL ,
page varchar( 255 ) NOT NULL default '',
counter int( 10 ) unsigned NOT NULL default '0',
PRIMARY KEY ( id )
) TYPE = MYISAM ;
</pre>
<p>●データ管理用</p>
<pre>
CREATE TABLE axs_page (
page_id varchar( 255 ) NOT NULL default '',
page_name varchar( 255 ) NOT NULL default '',
counter int( 10 ) unsigned NOT NULL default '0',
last_ip varchar( 255 ) default NULL ,
UNIQUE KEY page_id ( page_id )
) TYPE = MYISAM ;
</pre>
<p>MySQLのバージョンは3.23.58みたいですね。どうでもいいけど。（いいんかい<br />
ログ取り用のPHPはこちら。</p>
<pre>
&lt;?
/*
●このクラスの使い方●
require_once("access.inc");
$access = new access(モード, 解析ページ);
$access-&gt;write();
*/

//アクセス解析クラス
class access {
&#x09;//プロパティ
&#x09;var $mode;
&#x09;var $time;&#x09;&#x09;&#x09;//アクセスした時間
&#x09;var $lang;&#x09;&#x09;&#x09;//言語環境
&#x09;var $char_set;&#x09;&#x09;//文字コード
&#x09;var $ref;&#x09;&#x09;&#x09;//リファラ
&#x09;var $ua;&#x09;&#x09;&#x09;//UA
&#x09;var $ip;&#x09;&#x09;&#x09;//IP
&#x09;var $host;&#x09;&#x09;&#x09;//ホスト
&#x09;var $page;&#x09;&#x09;&#x09;//解析ページ
&#x09;var $db;&#x09;&#x09;&#x09;//DBオブジェクト

&#x09;//コンストラクタ
&#x09;function access($mode = 0, $page, $ref = "") {
&#x09;&#x09;//DB接続
&#x09;&#x09;require_once("myDB.inc");

&#x09;&#x09;$this-&gt;time = time();
&#x09;&#x09;$this-&gt;mode = $mode;
&#x09;&#x09;$this-&gt;page = $page;
&#x09;&#x09;$this-&gt;db = $db;

&#x09;&#x09;if($mode) {
&#x09;&#x09;&#x09;$this-&gt;ref = $ref;
&#x09;&#x09;} else {
&#x09;&#x09;&#x09;$this-&gt;ref = $_SERVER['HTTP_REFERER'];
&#x09;&#x09;}
&#x09;&#x09;$this-&gt;lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
&#x09;&#x09;$this-&gt;char_set = $_SERVER['HTTP_ACCEPT_CHARSET'];
&#x09;&#x09;$this-&gt;ua = $_SERVER['HTTP_USER_AGENT'];
&#x09;&#x09;$this-&gt;ip = $_SERVER['REMOTE_ADDR'];
&#x09;&#x09;$this-&gt;host = $_SERVER['REMOTE_HOST'];
&#x09;&#x09;if(!($this-&gt;host)) {
&#x09;&#x09;&#x09;$this-&gt;host = gethostbyaddr($this-&gt;ip);
&#x09;&#x09;}
&#x09;}

&#x09;//ログ書き込み
&#x09;function write() {
&#x09;&#x09;$sql = "select last_ip from axs_page where page_id = '" . $this-&gt;page . "'";
&#x09;&#x09;$res = $this-&gt;db-&gt;query($sql);
&#x09;&#x09;$row = $res-&gt;fetchRow();
&#x09;&#x09;$last_ip = $row[0];

&#x09;&#x09;$sql = "select id, " . $this-&gt;time . " - unix_timestamp(axs_date) from access where page = '" . $this-&gt;page . "' order by axs_date desc limit 1";
&#x09;&#x09;$res = $this-&gt;db-&gt;query($sql);
&#x09;&#x09;$row = $res-&gt;fetchRow();
&#x09;&#x09;$id = $row[0];
&#x09;&#x09;$interval = $row[1];

&#x09;&#x09;//連続アクセス判定
&#x09;&#x09;if($last_ip == $this-&gt;ip &amp;&amp; $interval &lt; 600) {
&#x09;&#x09;&#x09;$sql = "update access set counter = counter + 1 where id = " . $id;
&#x09;&#x09;&#x09;$res = $this-&gt;db-&gt;query($sql);
&#x09;&#x09;} else {
&#x09;&#x09;&#x09;$sql = "update axs_page set last_ip = '" . $this-&gt;ip . "', counter = counter + 1 where page_id = '" . $this-&gt;page . "'";
&#x09;&#x09;&#x09;$res = $this-&gt;db-&gt;query($sql);

&#x09;&#x09;&#x09;$sql = "insert into access (axs_date, lang, char_set, ref, ua, ip, host, page, counter) values(from_unixtime(?), ?, ?, ?, ?, ?, ?, ?, 1)";
&#x09;&#x09;&#x09;$sth = $this-&gt;db-&gt;prepare($sql);
&#x09;&#x09;&#x09;$res = $this-&gt;db-&gt;execute($sth, array($this-&gt;time, $this-&gt;lang, $this-&gt;char_set, $this-&gt;ref, $this-&gt;ua, $this-&gt;ip, $this-&gt;host, $this-&gt;page));
&#x09;&#x09;}

&#x09;}

&#x09;//カウンタ表示
&#x09;function dispCounter() {
&#x09;&#x09;$sql = "select counter from axs_page where page_id = '" . $this-&gt;page . "'";
&#x09;&#x09;$res = $this-&gt;db-&gt;query($sql);
&#x09;&#x09;$row = $res-&gt;fetchRow();
&#x09;&#x09;return $row[0];
&#x09;}
}
?&gt;
</pre>
<p>途中にあるmyDB.incは単にDB接続用のインスタンスを$dbに代入してるだけです。色々いい事が書いてあるんで見せられません。＾＾；<br />
で、解析したいページに以下のコードを挿入すればおｋ。</p>
<pre>
require_once("access.inc");
$access = new access(0, "top");
$access-&gt;write();
</pre>
<p>オブジェクト生成する時にコンストラクタの第1引数にモードを渡してますけど、通常は「0」でいいです。<br />
なんらかの事情で別の手段でログを取りたい時は、以下のようなコードを書いて&lt;img&gt;タグなどで読み込ませます。</p>
<pre>
&lt;?
require_once("access.inc");

if(isset($_GET['ref'])) {
&#x09;$ref = $_GET['ref'];
} else {
&#x09;$ref = "";
}
$access = new access(1, $_GET['id'], $ref);
$access-&gt;write();

header("Content-type: image/gif");
readfile("dummy.gif");
?&gt;
</pre>
<p>リファラは、JavaScriptなんかで渡してやると……。このやり方だとクローラは拾えないですけどね。</p>
<p>今回はまったのはWikiでした。なんか、UAが取れない。超わかんない。で、Wikiがインストールされてるディレクトリを全文検索してみた……。</p>
<pre>
※init.php

$ua = 'HTTP_USER_AGENT';
$user_agent = $matches = array();

$user_agent['agent'] = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
unset(${$ua}, $_SERVER[$ua], $HTTP_SERVER_VARS[$ua], $ua);&#x09;// safety
</pre>
<p>Σ(ﾟДﾟ；)</p>
<p>ごめんなさい、$_SERVER[$ua]の部分、削除しちゃいましたごめんなさいごめんなさいごめんなさい……。<br />
これのせいでなんか変な脆弱性とか出てきたらどうしよ。……まあいいんだけど。（いいんかい</p>
<p>とまあ、こんな感じで。気が向いたらログ表示用のPHPコードも公開するかも？　ただ、もうちょっと高機能でないと見ても面白くないだろうなあ……。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chisyamori.com/kay/2006/01/06/7/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
