<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
 xml:lang="ja"
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns="http://purl.org/rss/1.0/">
<channel rdf:about="http://tonextone.com/note/rss.rdf">
<title>tonextone.com/note/</title>
<link>http://tonextone.com/note/</link>
<description>Summary for tonextone.com/note/</description>
<dc:language>ja</dc:language>
<dc:rights>Copyright ©master_at_tonextone.com All rights reserved.</dc:rights>
<dc:creator>master_at_tonextone.com</dc:creator>
<dc:date>2006-09-01T00:00:00+09:00</dc:date>
<items><rdf:Seq>
<rdf:li rdf:resource="http://tonextone.com/note/20060901.html" />
<rdf:li rdf:resource="http://tonextone.com/note/diary/20060612.html" />
<rdf:li rdf:resource="http://tonextone.com/note/diary/20060529.html" />
<rdf:li rdf:resource="http://tonextone.com/note/diary/20060528.html" />
<rdf:li rdf:resource="http://tonextone.com/note/diary/20060316.html" />
<rdf:li rdf:resource="http://tonextone.com/note/diary/20060227.html" />
<rdf:li rdf:resource="http://tonextone.com/note/20051231.html" />
<rdf:li rdf:resource="http://tonextone.com/note/diary/20051223.html" />
<rdf:li rdf:resource="http://tonextone.com/note/diary/20051222.html" />
<rdf:li rdf:resource="http://tonextone.com/note/diary/server/20051213.html" />
<rdf:li rdf:resource="http://tonextone.com/note/essay/20051212.html" />
<rdf:li rdf:resource="http://tonextone.com/note/diary/20051207.html" />
<rdf:li rdf:resource="http://tonextone.com/note/diary/20051206.html" />
<rdf:li rdf:resource="http://tonextone.com/note/diary/20051204.html" />
<rdf:li rdf:resource="http://tonextone.com/note/diary/20051127.html" />

</rdf:Seq></items>
</channel>
<item rdf:about="http://tonextone.com/note/20060901.html">
<title>09/01 ブログシステム乗り換えます。</title>
<link>http://tonextone.com/note/20060901.html</link>
<description><![CDATA[
MT を使ってみます。<br />
今後、はこちら↓に書いていきます。<br />
    <a href ="http://tonextone.com/type/">/type/</a>
  
]]></description>
<dc:date>2006-09-01T00:00:00+09:00</dc:date>
</item>
<item rdf:about="http://tonextone.com/note/diary/20060612.html">
<title>06/12 open_basedir の 怪</title>
<link>http://tonextone.com/note/diary/20060612.html</link>
<description><![CDATA[
open_basedir が微妙…という話。<br />
PHP は、mod_php での運用がデファクトスタンダードになっている。<br />
    共用のレンタルサーバでも、mod_php が使えるのが普通だろう。<br />
    <br />
    で、safe_mode, open_basedir なわけである(<a href="http://jp2.php.net/manual/ja/security.apache.php" target="_blank">参考</a>)。<br />
    <br />
    私がこれまで構築してきたサービスは、<br />
    専用サーバで、管理者アカウントを外部に配布しない、<br />
    いわゆる「自社サービス」がほとんどだったので、<br />
    safe_mode, open_basedir 系は実際に本気で使った経験が無かった。<br />
    <br />
    で、最近構築しているサービスが、複数の仮想ホストでの運用になるので、<br />
    初めて本気で open_basedir を使ってみた。<br />
    <br />
    …これが、なかなか上手くいかなかった。<br />
    ここ2ヶ月くらい、試しては上手くいかず、あきらめ切れず、また試す…<br />
    の繰り返しだったが、やっと上手くいった。<br />
    <br />
    合理的な原因が見つかっていないので、様子をみている段階だが、<br />
    現段階の結論:<br />
    <blockquote>
    httpd.conf で、 open_basedir の設定をしている場合、<br />
    .htaccess で、 mbstring.* 系の設定をすると、<br />
    open_basedir が不具合を起こすようだ。<br />
    php.ini / ini_set() なら大丈夫っぽい。<br />
    </blockquote>

    <br />

    以下、現象 〜 経過を早送り:<br />

    <ul>
      <li>
        open_basedir の設定を httpd.conf の&lt;VirtualHost&gt;コンテナに書くと、<br />
        以下のようなエラーが出る。
<pre>
PHP Fatal error:  Unknown: Cannot find serialization handler xxx in Unknown on line 0, referer: xxxxxxxxx
</pre>
        mod_php が PHP の構文解析に失敗しているような感じ。
      </li>
      <li>
        このエラーの再現率は、30% 程度。
      </li>
      <li>
        zend-multibyte, Zend Optimizer を怪しむ(野生の勘)。
      </li>
      <li>
        怪しい部分について、有効 / 無効を切替えたり、<br />
        考え得る設定の組み合わせを、ほとんど総当りで試す。<br />
      </li>
      <li>
        解決の兆しも見えず…。
      </li>
      <li>
        やけになって、デフォルトの php.ini で試す。
      </li>
      <li>
        相変わらず…(´Д⊂ ﾓｳﾀﾞﾒﾎﾟ
      </li>
      <li>
        .htaccess での設定とか、ini_set() 系の設定も消してみる。
      </li>
      <li>
        <span style="font-size: 20px;">あ、</span>良さそう。
      </li>
      <li>
        設定調整して様子見。&laquo; 今ここ。
      </li>
    </ul>

    なんていうか、微妙すぎ…。

  
]]></description>
<dc:date>2006-06-12T00:00:00+09:00</dc:date>
</item>
<item rdf:about="http://tonextone.com/note/diary/20060529.html">
<title>05/29 俺的PHP似非フレームワーク</title>
<link>http://tonextone.com/note/diary/20060529.html</link>
<description><![CDATA[
「ページ・コントローラ」で「リア・コントローラ」。PHP ならではのフレームワーク的なモノ。<br />
<a href="http://tonextone.com/note/diary/20060528.html">前のエントリ</a>で、まとめるって言ったけど、<br />
    そんな大層なものでもないし、ちゃんとまとめる自信が無くなってきたので、<br />
    とりあえず簡単に説明すると…

    <h4>
      スクリプトを埋め込めるんだから、PHP 自体がテンプレートシステム。
    </h4>
    <dl>
      <dt>メリット</dt>
      <dd>
        テンプレートシステムを導入しなくて良い。<br />
        <br />
      </dd>
      <dt>デメリット</dt>
      <dd>
        PHP そのものなので、何でもできてしまうという意味で、リスクがある。<br />
        <br />
      </dd>
    </dl>

    <h4>
      テンプレート上の HTML コードは、関数として定義する(必要であればブロックに分けて)。
    </h4>
    例えば、テンプレート上に、ループするブロックがある場合、<br />
    そのブロックの始まりと、終わりに、関数定義の始まりと、終わりを埋め込む。<br />
    つまり、
    <pre>&lt;? function hoge_loop($_){ ?&gt;</pre>
    と、
    <pre>&lt;? } /* function hoge_loop($_) */ ?&gt;</pre>
    とで、囲む。<br />
    ブロック内で展開したい変数は、'$_' という連想配列に入れて引数として渡す。<br />
    残りのブロックも同様に関数化する。<br />
    「レンダリング」= 関数のコール。<br />
    <dl>
      <dt>メリット</dt>
      <dd>
        「レンダリング」を、ブロック単位で制御できる。<br />
        <br />
      </dd>
      <dt>デメリット</dt>
      <dd>
        テンプレートに、&lt;? function foo_bar($_){ ?&gt; とか記述されていてキモい(が、もう慣れた)。<br />
        間違って消されると「そんな関数見つかりません」系のエラーが発生する。<br />
        <br />
      </dd>
    </dl>

    <h4>
      ヴューに対してリクエストがあって、対応するコントローラが読み込まれる。
    </h4>
    テンプレートたる PHP ファイルから、<strong>ロジックが別ファイルとして分離されて</strong>、<br />
    <strong>ヴュー → コントローラ の対を成す</strong>。<br />
    &raquo;<strong>「ページ・コントローラ」!</strong><br />
    <br />
    <strong>ヴューがリクエストを受けて、ヴューがコントローラを読み込む</strong>イメージ。<br />
    (フロント・コントローラの逆…)<br />
    &raquo;<strong>「リア・コントローラ」!!</strong><br />
    <br />
    特定のヴューに対応するコントローラは、<br />
    ヴューの SCRIPT_FILENAME から 1 対 1 に自動決定され、include 系の命令で読み込まれる。<br />
    そのコントローラの中で、<br />
    ブロック単位で、テンプレートの「レンダリング」(=関数のコール)が行われる。<br />
    <br />
    ついでに、拡張子 html で mod_php が動作するように設定して、<br />
    テンプレートたる PHP ファイルの拡張子は html とする。<br />

    <dl>
      <dt>メリット</dt>
      <dd>
        「ページ・コントローラ」の〜:<br />
        ロジックがページ単位で分割されるので、<br />
        工数を見積もる際に見通しが良く、メンテナンスも容易。<br />
        <br />
        「リア・コントローラ」の〜:<br />
        mod_rewrite やら、ルーティングやら、による仮想 URL じゃなくて、<br />
        静的 HTML と同様に、URL に対応するパスに<br />
        HTML っぽいファイル(実は PHP)が実在するので分りやすい<br />
        (テンプレートを担当するデザイナにも受け入れられやすい)。<br />
        <br />
      </dd>
      <dt>デメリット</dt>
      <dd>
        「同一の URL に対するリクエストだけれど、<br />
        　リクエスト変数によって条件分岐してヴューを切替えたい」というような場合には、<br />
        例外的にフロント・コントローラ的なものを配置する必要がある。<br />
        <br />
      </dd>
    </dl>

    <h4>
      モロモロの処理を auto_prepend, auto_append .
    </h4>
    上記の、 ヴュー → コントローラ の対応付けや、<br />
    その他、お決まりの処理(セキュリティ対策、DB接続、セッション、認証など)は、<br />
    1 つのファイル(prepend.php とか)にまとめておいて、それを auto_prepend .<br />
    更に、コントローラの読み込みや、その他、後始末系の処理も、<br />
    1 つのファイル(append.php とか)にまとめておいて、それを auto_append .<br />
    <dl>
      <dt>メリット</dt>
      <dd>
        テンプレートたる PHP ファイルに、include 系の命令が一切露出しないので、<br />
        テンプレートとしてスッキリするし、ちょっとだけセキュアな気もする。<br />
        <br />
      </dd>
      <dt>デメリット</dt>
      <dd>
        あるのかもしれないが特に感じない。<br />
        <br />
      </dd>
    </dl>

    <h4>
      include 系を随所で使う。
    </h4>
    フロント・コントローラでは、全ての処理が一箇所に集まるので DRY にしやすいが、<br />
    「ページ・コントローラ」では事情が違う。<br />
    代わりに、include 系の命令を多用する事で、DRY を追求する。<br />
    <dl>
      <dt>メリット</dt>
      <dd>
        あるのかもしれないが特に感じない。<br />
        <br />
      </dd>
      <dt>デメリット</dt>
      <dd>
        ルールが無いと見通しが悪くなる。<br />
        <br />
      </dd>
    </dl>

    <h4>
    という感じなんだけど…
    </h4>
    PHP でしかあり得ない仕組みなので、他の言語から見ると気持ち悪いだろうけれど、<br />
    デザイナとの分業のし易さを追求した結果の産物であって、<br />
    実際、その意味では充分な効果が得られたと思う。<br />
    <br />
    幸か不幸か、私がまともに使えるのは PHP だけなので、<br />
    今でも、特に違和感も不便も感じず、普通に使っているけれど、<br />
    そろそろ、その違和感とか不便さを理解しといたほうが良い気がする(汗笑)。<br />
    <br />
    それには、PHP 以外を使ってみる必要があるだろう、<br />
    というわけで、 Perl を改めて勉強しようと思った次第。<br />
  
]]></description>
<dc:date>2006-05-29T00:00:00+09:00</dc:date>
</item>
<item rdf:about="http://tonextone.com/note/diary/20060528.html">
<title>05/28 PHP の強み</title>
<link>http://tonextone.com/note/diary/20060528.html</link>
<description><![CDATA[
PHP の特長を活かすには、どんな風に使ったら良いだろうか?<br />
「<a href="http://labs.gree.jp/Top/Study/20060528.html">オープンソーステクノロジー勉強会 第3回</a>」に参加した。<br />
    今回のテーマはウェブアプリケーションフレームワーク。<br />
    高橋さんが RoR 、藤本さんが Ethna の紹介をするという、大変に豪華な勉強会だった。<br />
    <br />
    高橋さんのお話で興味深かった点をメモ:<br />

    <h4>RoR: 実行環境の現状。</h4>
    <dl>
      <dt>Apache + mod_ruby :</dt>
      <dd>
        ruby が富豪的なので、<br />
        実際は、Apache + mod_ruby をアプリ専用にして、<br />
        フロントにもう一個ウェブサーバ立てるのが普通。<br />
        → 面倒。
      </dd>
      <dt>じゃあ、WEBrick とか:</dt>
      <dd>
        フロントに Apache 立てておいて、<br />
        アプリ専用のウェブサーバは WEBrick で。<br />
        <pre>$ apachectl graceful;</pre>
        的な仕組みが無い。
      </dd>
      <dt>Apache + FastCGI :</dt>
      <dd>不安定?</dd>
      <dt>Lighttpd + FastCGI :</dt>
      <dd>結構、使われている。でも、Apache ほど多機能ではない。</dd>
    </dl>

    <h4>RoR: 日本語化の現状。</h4>
    <dl>
      <dt>
        <a href="http://jp.rubyist.net/magazine/?0012-RubyOnRails">ActiveHeart</a> :
      </dt>
      <dd>
        シンプルなので汎用性がある。
      </dd>
      <dt>
        <a href="http://wota.jp/ac/?date=20060204">スペジェネ</a> :
      </dt>
      <dd>
        情熱的なので、ハマる場合と、ハマらない場合がある。
      </dd>
      <dt>
        gettext :
      </dt>
      <dd>
        本格的だが敷居が高い。
      </dd>
    </dl>

    <h4>RoR: 文字コードの現状。</h4>
    <dl>
      <dt>
        デフォルトの文字コード指定 :
      </dt>
      <dd>
        $KCODE = 'u'; # s,e,n
      </dd>
      <dt>
        フィルタで変換 :
      </dt>
      <dd>
        before/after filter に、NKF, iconv フィルタとかを挿せる。
      </dd>
    </dl>

    <br />
    で、PHPはどうなんだ。<br />
    <br />

    <h4>PHP: Apache の mod_* だけど…</h4>
    <dl>
      <dt>mod_perl, mod_ruby</dt>
      <dd>
        Apache を LL で拡張するためのモジュール。<br />
        → 玄人向き。
      </dd>
      <dt>mod_php</dt>
      <dd>
        Apache で LL を処理するためのモジュール。<br />
        → それ以外できない。潔い。安全。
      </dd>
    </dl>

    <h4>PHP: 広く普及している。</h4>
    普及率が高くて実行環境も mod_php が標準的。<br />
    共用レンタルサーバとかでも普通に提供されている。<br />
    したがって、既存のシステムの改修などにも利用し易い。<br />
    <br />
    &lt;所感&gt;<br />
    <br />
    共用レンタルサーバとかでも mod_php が採用されているのは、<br />
    mod_perl, mod_ruby と違って「必要最低限の事しかできない」からだと思う。<br />
    とは言え、mod_* であるからには、Apache の権限で実行されるので、<br />
    mod_* に関わる全てのファイルのパーミションは、<br />
    ---赤の他人のファイルであろうとも---<br />
    Apache が読めるようになっている事が「必要」であり、<br />
    重要な情報を隠蔽する事が難しい(できない?)。<br />
    にもかかわらず PHP は共用サーバにも普及してしまったので、苦肉の策として<br />
    safe_mode, open_basedir <br />
    などの設定項目が設けられている。<br />
    <br />
    &lt;/所感&gt;<br />
    <br />

    <h4>PHP: フレームワークは?</h4>
    フロント・コントローラなフレームワークが主流だが、既存のシステムとの共存が難しいのではないか?<br />
    PHP の強みを活かすには、「ページ・コントローラ」なフレームワークのほうが、<br />
    既存のシステムと共存しやすくて良いのでは?<br />
    <br />
    &lt;所感&gt;<br />
    <br />
    「ページ・コントローラ」というのは、ページ毎にコントローラを持つという事。<br />
    フロント・コントローラ主流の昨今において、「ページ・コントローラ」は原点回帰とも言える。<br />
    最近 PHP 界隈で、そういう話がチラホラ出ているけど、半分はネタだと思う。何となく。<br />
    実際、高橋さんの話もネタだと思う。<br />
    <br />
    でも、私が 5 年ほど使い続けているフレームワーク的なモノも、<br />
    そんな「ページ・コントローラ」に該当する気がする。<br />
    ネタではなくマジで使い込んでしまっている。<br />
    なので、「ページ・コントローラ」の実装例として、後でちゃんとまとめる事にしよう。<br />
    <br />
    &lt;/所感&gt;<br />
  
]]></description>
<dc:date>2006-05-28T00:00:00+09:00</dc:date>
</item>
<item rdf:about="http://tonextone.com/note/diary/20060316.html">
<title>03/16 JavaScript による min-height, max-height の実装。</title>
<link>http://tonextone.com/note/diary/20060316.html</link>
<description><![CDATA[
探すよりも作ったほうが速そうだったので。<br />
動的なウェブサイトなどで、画面上のボックスの内容量が予測できない場合、<br />
    CSS で overflow なんか使ったりします。ですよね?<br />
    でも、overflow なボックスのサイズが固定だと、逆にまだ何も内容が無い場合に、余白になってしまいます。<br />
    「じゃあ、 max-width, max-height を使おうよ」と言う事になるのですが、<br />
    min-width, max-width, min-height, max-height は IE で実装されてません。このやろう。<br />
    <br />
    なので、JavaScript で実現する感じのモノを作りました。
    <a href="http://tonextone.com/neta/min_max/test.html">&raquo;デモ</a><br />
    仕組みは単純なので、興味があったら、ソース読んでください。<br />
  
]]></description>
<dc:date>2006-03-16T00:00:00+09:00</dc:date>
</item>
<item rdf:about="http://tonextone.com/note/diary/20060227.html">
<title>02/27 ちょっと安全かもしれない eval() の使い方。</title>
<link>http://tonextone.com/note/diary/20060227.html</link>
<description><![CDATA[
今思いついたので、穴がありそうなのですが。<br />
長らくエントリのない状態が続いた後ですが、<br />
    地味な思いつきのメモです。<br />
    <br />
    eval() 使ったらスゲェ簡単なのに…とか思いながら、<br />
    その強力さゆえに、恐ろしくて使えない場合が、間々ある。<br />
    いつも奥の手として持ってるだけみたいな。<br />
    <br />
    良くあるのは、
    <pre>'こんにちは、{$foo}さん。ようこそ{$bar}のホメパゲへ。'</pre>
    みたいな文字列の中の変数に値を代入したいというやつ。<br />
    <br />
    正規表現とかでやってたら回りくどいので、<br />
    何とか eval() を活用するためにセキュリティ対策を考えてみた。<br />
    <br />
    ヒアドキュメント使うのがキモ。<br />
    あと、ちゃんと意識して引用符「'」「"」を使い分けて、<br />
    1 回しか評価しないように気を付ける。<br />
    ついでに、境界識別子 '$_boundary' を予測し難くすれば、悪い事もやりにくかろう。<br />
    <br />
    PHP だと、こんな感じ。<br />
<pre>
&lt;?
function eval_vars_in_string($_string,$_vars)
{
  extract($_vars);

  $_boundary = uniqid('__');

  $_code = '$_return = &lt;&lt;&lt;'.$_boundary.'
'.$_string.'
'.$_boundary.';
';

  eval($_code);

  return $_return;
}

$_string = 'こんにちは、{$foo}さん。ようこそ{$bar}のホメパゲへ。';

$_out = eval_vars_in_string($_string,$_POST);

?&gt;
</pre>
    <br />
    という思い付きでした。[<a href="http://tonextone.com/neta/eval_vars_in_string/">サンプル</a>]<br />
    <br />
    コメント歓迎。
  
]]></description>
<dc:date>2006-02-27T00:00:00+09:00</dc:date>
</item>
<item rdf:about="http://tonextone.com/note/20051231.html">
<title>12/31 新年の挨拶</title>
<link>http://tonextone.com/note/20051231.html</link>
<description><![CDATA[
都合により、早めのご挨拶<br />
新年、明けましたらおめでとうございます。<br />
    <br />
    2005年は、大変お世話になり、<br />
    お蔭様で、私としては大きな一歩を踏み出す事ができました。<br />
    2006年は、次の展開を自ら作り出せるかどうかの正念場と心得ております。<br />
    <br />
    よろしくご指導ご鞭撻下さいますよう、心よりお願い申し上げます。<br />
    [<a href="http://tonextone.com/neta/greeting/2006/">謹賀新年2006_犬.html</a>]
  
]]></description>
<dc:date>2005-12-31T06:00:00+09:00</dc:date>
</item>
<item rdf:about="http://tonextone.com/note/diary/20051223.html">
<title>12/23 PostgreSQL で RDB 設計 その2</title>
<link>http://tonextone.com/note/diary/20051223.html</link>
<description><![CDATA[
RDB の設計再考<br />
「<a href="http://tonextone.com/note/diary/20051222.html">PostgreSQL で RDB 設計 その1</a>」の補足。<br />

    PostgreSQL では、WHERE 句に、正規表現が使えるので、いつも重宝している。<br />
    こんな感じ。<br />
    <ul>
      <li>使用前:
<pre>
select * from some_table where some_field = 1 or some_field = 4 or ... ;
</pre>
      </li>
      <li>使用後:
<pre>
select * from some_table where some_field ~ '^(1|4|...)$';
</pre>
      </li>
    </ul>

   で、配列型のフィールド 'some_array' に対しても、<br />
   ANY(some_array) をカマせば、これができるだろうと期待していた。<br />
   <br />
   いろいろ試したが、どうも無理っぽい[マニュアルより <a href="http://www.postgresql.org/docs/7.4/interactive/functions-comparisons.html#AEN12704" target="_blank">ANY/SOME(array)</a>]。<br />
   <br />
   そういう目的では、<br />
   配列型ではなく TEXT 型とかに配列表現を突っ込むのが良いだろう。<br />
   とりあえず TEXT 型で用意しておいて、記法は充分検討してゆっくり決めれば良い。<br />
   <br />
   例えば、PHP の serialize(); の場合、数値配列は、
<pre>
a:2:{i:0;i:123;i:1;i:456;}
</pre>
   という感じで、キーと値とが交互に表れるが、<br />
   このキーと値との選り分けを正規表現なんかでやってられない。<br />
   そうなると独自記法がベストな気がしてきた( JSON とか XML とかも無意味に面倒)。<br />
   <br />
   正規表現のメタキャラクタとして解釈されなくて、<br />
   尚且つ、データに使われなさそうな文字列を、セパレータにすれば良い。<br />
   クォーテーションの扱いにも注意。<br />
   <br />
   以下、例:<br />

<pre>
create table fruit
(
fruit_id     serial,
name         text
);

create table member
(
member_id    serial,
name         text,
gender       text,
fruit        text
);

insert into fruit(name) values('りんご');
insert into fruit(name) values('みかん');
insert into fruit(name) values('いちご');
insert into fruit(fruit_id,name) values(12,'いちじく');

insert into
member(name,gender,fruit)
values('太郎','男',':::::1:::::3:::::');

insert into
member(name,gender,fruit)
values('花子','女',':::::2:::::3:::::');

insert into
member(name,gender,fruit)
values('次郎','男',':::::12:::::');

select * from member,fruit
where member.fruit ~ (select ':{5}'||fruit.fruit_id||':{5}')
order by member_id;

 member_id | name | gender |      fruit        | fruit_id |   name
-----------+------+--------+-------------------+----------+----------
         1 | 太郎 | 男     | :::::1:::::3::::: |        1 | りんご
         1 | 太郎 | 男     | :::::1:::::3::::: |        3 | いちご
         2 | 花子 | 女     | :::::2:::::3::::: |        2 | みかん
         2 | 花子 | 女     | :::::2:::::3::::: |        3 | いちご
         3 | 次郎 | 男     | :::::12:::::      |       12 | いちじく
(5 rows)
Time: 1.069 ms

select * from member
where fruit ~ ':{5}(2|3):{5}'
order by member_id;

 member_id | name | gender |      fruit
-----------+------+--------+-------------------
         1 | 太郎 | 男     | :::::1:::::3:::::
         2 | 花子 | 女     | :::::2:::::3:::::
(2 rows)

Time: 0.557 ms
</pre>

  
]]></description>
<dc:date>2005-12-23T00:00:00+09:00</dc:date>
</item>
<item rdf:about="http://tonextone.com/note/diary/20051222.html">
<title>12/22 PostgreSQL で RDB 設計 その1</title>
<link>http://tonextone.com/note/diary/20051222.html</link>
<description><![CDATA[
RDB の設計再考<br />
4 年くらい前から PostgreSQL を使っている。<br />
    MySQL は、システム上必要な場合以外は使っていない。<br />
    <br />
    MySQL が嫌いなわけではなく、<br />
    「何かみんな MySQL だなぁ…俺も MySQLer になろうかなぁ。」<br />
    と思ったことは数知れず。<br />
    <br />
    でも、PostgreSQL にしかない機能の恩恵に、度々、与ってしまっているので、「乗り換え」には至らず。<br />
    <br />
    それにしても、いろいろな RDBMS があるものだ
    (
    <a href="http://www.fabalabs.org/research/papers/FabalabsResearchPaper-OSDBMS-Eval.pdf" target="_blank">RDBMS比較資料</a>[PDFです]
    )。<br />
    <br />
    各 RDBMS の特徴は、DB の設計や、チューニングの際に、顕著になるのではないだろうか?<br />
    「管理しやすくて、検索が速くて、更新もサクサクできる」<br />
    そんな DB はどうしたら実現できるだろうか…と考えていくと、自然と実装の話になっていく。<br />
    (もちろん DB を抽象化してポータブルに作っておく事が要求される場合は別。)<br />
    <br />
    ということで、前置きが長くなったが、 PostgreSQL でいろいろ試したメモ。<br />

    <h4>データのセグメンテーション</h4>
    PostgreSQL のデータは、<br />
    <pre>cluster ⊃ database ⊃ schema ⊃ table</pre>
    という階層の最下層であるところの 'table' に保存されるが、<br />
    これらの各階層で権限の設定ができる。<br />
    <br />
    「複数ユーザ(100 アカウント程度)を想定した場合、どの階層で分断するのが現実的か?」<br />
    というのを、改めてマジメに考えてみた。<br />
    <br />

    以下、 アカウント [user] のデータ識別子を [user] とする。
    <ol>

     <li>
      table :
<pre>
=> create table [user]_table(...);
=> grant all on [user]_table to [user];
</pre>
      却下<br />
      (テーブルの一覧がすごい事になるため)。<br />
      <br />
     </li>

     <li>
      schema :
<pre>
$ createuser -P [user];
=> /* public は PUBLIC に grant されてるので消す。*/
=> drop schema public;
=> create schema [user] authorization [user];
</pre>
      却下<br />
      (<br />
      テーブルの一覧には [user] schema に属するテーブルしか現れないが、<br />
      スーパーユーザにも見えにくくなるため。<br />
      )<br />
      <br />
     </li>

     <li>
      database :
<pre>
$ createdb [user];
$ createuser -P [user];
</pre>
      採用<br />
      (もっとも現実的)<br />
      <br />
     </li>

     <li>
      cluster :
<pre>
$ initdb -D /path/to/[user];
</pre>
      で、ポートを切替えて運用。<br />
      …却下でしょう。<br />
      <br />
     </li>

    </ol>
    ユーザ毎のデータは database のレベルで分断するのが現実的。<br />
    当たり前の結論に至り、なんか安心。<br />

    <h4>選択型データの保存形式</h4>
    例えば、<br />
    「<br />
    好きな果物はなんですか?<br />
    A. りんご<br />
    B. みかん<br />
    C. いちご<br />
    ...<br />
    P. いちじく<br />
    」<br />
    という問いに対する回答を保存したい場合、
    <ol>
     <li>RAW: 'りんご'とか'いちご'という内容を保存すべきか?</li>
     <li>CODE: 'A'とか'C'というコードを保存すべきか?</li>
    </ol>
    <br />
    ◆RAW に対する CODE の strong / weak points :<br />
    <br />
    [管理系]<br />
    Ｏ コードと内容との対応を外部で一元管理できるので修正が容易。<br />
    Ｘ コードと内容との対応表が無いとデータとして成立しない。<br />
    <br />
    [検索系]<br />
    Ｏ データが簡潔に表せるのでちょっと速いかも。<br />
    Ｘ 特になし。<br />
    <br />
    [更新系]<br />
    Ｏ 特になし。<br />
    Ｘ 特になし。<br />
    <br />
    管理系の視点で CODE のほうが有利と判断する。<br />
    これも「正規化」に通じる当たり前の結論。<br />
    ただし、コードと内容との対応表(マスターテーブル) の死守が前提。<br />

    <h4>データ構造の保存</h4>
    例えば、
<pre>
members =
[
    {
      'name': '太郎',
      'gender': '男'
      'fruits': [1, 3]
    },

    {
      'name': '花子',
      'gender': '女'
      'fruits': [2, 3, 11]
    }
];
</pre>
    というデータ構造を保存したい場合、
    <ol>
     <li>
      NORMAL: <br />
      データの値 1 つをフィールド 1 つに( 1 対 1 に)保存するべきか?<br />
      上の例の場合、正規化後のテーブルは 3 つか 4 つになるはず。<br />
      <br />
     </li>
     <li>
      BULK: <br />
      上の例(意図的に JSON で記述してある)のように、<br />
      「データのラベルや値を含む構造そのものを適切に表現する文字列」<br />
      として保存するべきか?<br />
      <br />
     </li>
    </ol>
    BULK の例としては、JSON の他に、<br />
    PHPコードそのもの( array('name'=>'太郎',...) )、<br />
    それを serialize(); したもの、あるいは、XML などを想定している。<br />
    また、少し毛色が違うが、PostgreSQL の配列型データも、BULK の一種として考える。<br />
    <br />
    ◆NORMAL に対する BULK の strong / weak points :<br />
    <br />
    [管理系]<br />
    Ｏ データ構造とテーブル定義の結合度が低いので、より汎用性がある。<br />
    Ｘ データを直接操作しにくい ?<br />
    &nbsp;&nbsp;=> PostgreSQL の配列型では問題無し。<br />
    <br />
    [検索系]<br />
    Ｏ 主テーブルを検索するだけで、該当するデータ構造を取得できる。<br />
    Ｘ 直積を作りにくい ?<br />
    &nbsp;&nbsp;=> PostgreSQL の配列型では問題無し。<br />
    <br />
    [更新系]<br />
    Ｏ 主テーブルを更新するだけで、該当するデータ構造を更新できる。<br />
    Ｘ データ構造の部分的な更新がしにくい ?<br />
    &nbsp;&nbsp;=> PostgreSQL の配列型では問題無し。<br />
    <br />
    総合的に視て、BULK というか「 PostgreSQL の配列型」のほうが有利と判断する。<br />
    <br />
    以下、具体例<br />
    <ol>
     <li>NORMAL の場合:
<pre>
create table fruit
(
fruit_id     serial,
name         text
);

create table member
(
member_id   serial,
name        text,
gender      text
);

create table fruit_to_member
(
fruit_to_member_id    serial,
member_id             integer,
fruit_id              integer
);

insert into fruit(name) values('りんご');
insert into fruit(name) values('みかん');
insert into fruit(name) values('いちご');

insert into member(name,gender) values('太郎','男');
insert into member(name,gender) values('花子','女');

-- make relations;
insert into fruit_to_member(member_id,fruit_id) values(1,1);
insert into fruit_to_member(member_id,fruit_id) values(1,3);

-- make another relations;
insert into fruit_to_member(member_id,fruit_id) values(2,2);
insert into fruit_to_member(member_id,fruit_id) values(2,3);

select * from member,fruit
where fruit.fruit_id in ( select fruit_id from fruit_to_member
                          where fruit_to_member.member_id = member.member_id );

 member_id | name | gender | fruit_id |  name
-----------+------+--------+----------+--------
         1 | 太郎 | 男     |        1 | りんご
         1 | 太郎 | 男     |        3 | いちご
         2 | 花子 | 女     |        2 | みかん
         2 | 花子 | 女     |        3 | いちご
(4 rows)
Time: 0.784 ms
</pre>
     </li>
     <li>BULK の場合:
<pre>
create table fruit
(
fruit_id     serial,
name         text
);

create table member
(
member_id   serial,
name        text,
gender      text,
fruit       smallint[]
);

insert into fruit(name) values('りんご');
insert into fruit(name) values('みかん');
insert into fruit(name) values('いちご');

-- make record, with ARRAY;
insert into member(name,gender,fruit) values('太郎','男','{1,3}');

-- make another record, with ARRAY;
insert into member(name,gender,fruit) values('花子','女','{2,3}');

/*
 * where 2 = ANY(some_array)
 * (古い記法: where some_array *= 2)
 */
select * from member,fruit
where fruit.fruit_id = ANY(member.fruit)
order by member_id;

 member_id | name | gender | fruit | fruit_id |  name
-----------+------+--------+-------+----------+--------
         1 | 太郎 | 男     | {1,3} |        1 | りんご
         1 | 太郎 | 男     | {1,3} |        3 | いちご
         2 | 花子 | 女     | {2,3} |        2 | みかん
         2 | 花子 | 女     | {2,3} |        3 | いちご
(4 rows)
Time: 0.506 ms
</pre>
     </li>
    </ol>

    <h4>感想</h4>
    たまにマニュアルを読むと幸せになれる…と信じよう。

  
]]></description>
<dc:date>2005-12-22T02:00:00+09:00</dc:date>
</item>
<item rdf:about="http://tonextone.com/note/diary/server/20051213.html">
<title>12/13 サーバ管理その1</title>
<link>http://tonextone.com/note/diary/server/20051213.html</link>
<description><![CDATA[
linux ユーザによる FreeBSD でのサーバ管理<br />
tf-idf + bayesian-filter を試したいので、このサーバに chasen とか mecab とか入れる事にした。<br />
    で、かなり放置していたので、いろいろと整備した。<br />
    以下、メモ:<br />
    <h4>ports</h4>
    packageはコンパイル済だが、ports は未コンパイル。その分、強力。<br />
    ports の実体はスケルトン。↓こんな感じ。<br />
<pre>
$ tree /usr/ports/graphics/ImageMagick/
/usr/ports/graphics/ImageMagick/
|-- Makefile
|-- distinfo
|-- files
|   |-- patch-Makefile.in
|   |-- patch-coders::jp2.c
|   `-- patch-configure
|-- pkg-descr
`-- pkg-plist

1 directory, 7 files
</pre>
    <br />
    で、portupgrade っていう管理ユーティリティがあって便利。 linux の apt-get に相当する。<br />
<pre>
;; ports を最新にする。
$ cvsup -g /usr/local/etc/ports-supfile;

;; ports のデータベースを更新する。
$ portsdb --update --updateindex;

;; ports の内容を表示する。
$ portversion --verbose;

;; ports からインストールする。 (= cd /usr/ports/foo/var; make install clean; )
$ portinstall --verbose foo/var;

;; ports からアップグレードする。
$ portupgrade --interactive foo;

;; ports の作業ファイルを削除する。
$ portsclean --workclean --distclean;
</pre>
    <br />
    今回は、先ず、いろいろアップグレードした。
<pre>
$ portupgrade --interactive --all;
$ portsclean --workclean --distclean;
</pre>
    <br />
    それから、無くて困っていた screen をインストールした。<br />
    <a href="http://www.freebsd.org/ports/" target="_blank">FreeBSD Ports</a>で cvs から 'screen' を検索して、それが /usr/ports の下にあることを確認して、<br />
<pre>
$ portinstall --verbose sysutils/screen;
$ portsclean --workclean --distclean;
</pre>
    簡単。<br />
    <br />
    参考:
    <ol>
     <li>
      <a href="http://www.jp.freebsd.org/www.FreeBSD.org/doc/ja_JP.eucJP/books/handbook/ports.html" target="_blank">
       アプリケーションのインストール - packages と ports
      </a>
     </li>
     <li>
      <a href="http://iris.homeunix.net/yayoi/freebsd/inst/portupgrade.asp" target="_blank">
       portupgrade
      </a>
     </li>
    </ol>
    <br />

    <h4> src からインストール</h4>
    APP(ApachePostgresqlPhp) は、 src で管理している。<br />
    これも、ついでにアップグレード。<br />
    (apache-1.3.34 も出ているが、これは Apache-SSL が出るまで待つことにした。)<br />
    <ul>
     <li>postgresql-8.1.1</li>
     <li>php-4.4.1</li>
     <li>ZendOptimizer-2.6.0</li>
     <li>php-json-ext-1.1.0</li>
    </ul>
    PostgreSQL の migration も、<br />
    <br />
    [backup]
<pre>
pg_dumpall -g > /home/postgres/backup/all.dmp;
pg_dump -b -F c foo > /home/postgres/backup/foo.dmp;
</pre>

    [restore]
<pre>
psql -f all.dmp template1
pg_restore -d foo foo.dmp
</pre>
    で、無事完了。<br />
    <br />
    参考:
    <ol>
     <li>
      <a href="http://www.php.net/release_4_4_1.php" target="_blank">
       PHP 4.4.1. Release Announcement
      </a>
     </li>
     <li>
      <a href="http://www.postgresql.org/docs/8.1/interactive/index.html" target="_blank">
       PostgreSQL 8.1.0 Documentation
      </a>
     </li>
    </ol>
    <br />

    <h4>ハマりどころ</h4>
    最近 PHP のリリースが安定していないので、必要以上にビビっていたせいもあり、<br />
    実は結構ハマった。<br />

    <ol>
     <li>
      <dt>$ pkgdb -F;</dt>
      <dd>
       このサーバの構築に際して、上記 APP などを src で管理するために、<br />
       <a href="http://www.vps7.net/" target="_blank" >VPS7</a> の標準構成から package/ports 版をアンインストールして頂いた。<br />
       その際、PHP の拡張(php4-xxx) の package/ports が取り残されていたらしく、<br />
       存在しない apache との依存関係を引きずっているようだった。<br />
       とりあえず、
<pre>
$ pkgdb -F;
</pre>
       したら問題無さそう。<br />
       <br />
      </dd>
     </li>
     <li>
      <dt>autoconf,automake,libtool の重複</dt>
      <dd>
       ひとしきり portupgrade/portsclean して、<br />
<pre>
$ portversion --verbose;
</pre>
       してみたら、autoconf,automake,libtool がバージョン違いで複数ある。<br />
       不安に思いつつ、PHP を src からインストールする作業に取り掛かると、<br />
       configure で warning が出て、make も失敗。
<pre>
*** Warning: inter-library dependencies are not known to be supported.
*** All declared inter-library dependencies are being dropped.

*** Warning: libtool could not satisfy all declared inter-library
*** dependencies of module libphp4.  Therefore, libtool will create
*** a static module, that should work as long as the dlopening
*** application is linked with the -dlopen flag.
</pre>
       package/ports のツリーがイカレたか?<br />
       と思ったが、重複自体は問題ないらしい。<br />
       package/ports 間の依存関係の連鎖を最小限にするために、<br />
       被依存バージョンを残しつつ、別のバージョンもインストールする方針らしい。<br />
       とりあえず、libtool とかが見つからないのはマズい気がしてタマらなかったので、<br />
<pre>
$ ln -s /usr/local/bin/libtool15 /usr/local/bin/libtool
</pre>
       とか、しばらくゴニョゴニョやってたら、なんかコンパイルできた。<br />
       途中、不安が不安を呼んで、<br />
       config.log の fail とか warn とかの多さにくじけそうになったが、<br />
       もともと config.log は、そういうものらしいし、とりあえず動いてるのでヨシ。<br />
       <br />
      </dd>

     </li>
    </ol>

    ということで、PHP に不安が残るので、念のため php.ini を見直す予定。<br />
    本題の chasen, mecab を、src, ports のどっちで管理するかも要検討。

  
]]></description>
<dc:date>2005-12-13T04:00:00+09:00</dc:date>
</item>
<item rdf:about="http://tonextone.com/note/essay/20051212.html">
<title>12/12 理解/説明</title>
<link>http://tonextone.com/note/essay/20051212.html</link>
<description><![CDATA[
理解すること、説明すること。<br />
「ソレは何か?」<br />
    という問いに対して応えるために必要な作業は、<br />
    客観的に知覚できる限りの差異で<br />
    「ソレ」を「ソレ以外」から区別する作業ではなく、<br />
    問者の主観的なシナリオの中に抽象化された<br />
    「ソレ」と「ソレ以外」との関係性を描く作業である。<br />
    <br />
    そのためには、<br />
    その関係性を描くシナリオに、<br />
    問者のシっている「ソレ以外」を登場させ、それを足場にするか、<br />
    <br />
    あるいは、<br />
    そのシナリオ自体と、<br />
    問者のシっている別のシナリオとの類似性を頼りにするか、<br />
    <br />
    いずれにせよ、<br />
    問者のシっている物事から「ソレ」へと、想像を及ばせる事になるだろう。<br />
    <br />
    こういう作業のツールとしては、モデルが有効だ。<br />
    <br />
    モデルを表現するのに最適なのは視覚化であり、<br />
    その中でもよく使われるのは模式図(2次元的な視覚化)である。<br />
    <br />
    特定の状況を表す模式図においては、<br />
    その状況に登場する要素は<br />
    「名前」、「アイコン」、「変数」などの抽象化された記号で表され、<br />
    各要素間の関係性だけが視覚化される。<br />
    <br />
    各要素の内部構造は--- その要素自体の性質の由来であるが ---、<br />
    また別の模式図で表されるべきものである。<br />
    <br />
    物事の「記録/再生」は、あるいは「理解/説明」は、<br />
    いずれこのような作業だと思う。<br />
    <br />
    そして、これこそプログラミングの本質ではないだろうか?<br />
    <br />
    抽象化に関する、能力と、センスと、情熱には、個人差があり、<br />
    手法、ツールがそれを反映しているのだろうと思う。<br />
    <br />
    抽象化/記号の発明は偉大だ。<br />
    <br />
  
]]></description>
<dc:date>2005-12-12T00:00:00+09:00</dc:date>
</item>
<item rdf:about="http://tonextone.com/note/diary/20051207.html">
<title>12/07 MVC2.0 その3</title>
<link>http://tonextone.com/note/diary/20051207.html</link>
<description><![CDATA[
web2.0 時代の Ajax なウェブアプリケーションにおけるMVC。<br />
「<a href="http://tonextone.com/note/diary/20051206.html">MVC2.0 その2</a>」の続き。<br />

    web2.0 時代の AJAX なウェブアプリケーションにおける MVC について。<br />

    <h4>AJAX するデータの形式</h4>
    <ul>

      <li>
        Request(サーバへ送信されるデータの形式)の選択肢:<br />
        <br />
        <ol>
          <li>JSON</li>
          <li>XML</li>
          <li>PHP/serialize(など、サーバサイド言語固有のデータ記法)</li>
        </ol>
        <br />

        3. の場合は、XOAD のように、<br />
        サーバサイド言語でクライアントサイドのコードを生成することが前提となるだろう。<br />
        このような密結合は、 web2.0 にはそぐわないと思う。<br />
        <br />

        クライアントが Flash などの場合も考えれば、<br />
        2.の XML が、やはり最も中立的で、web2.0 的だろう。<br />
        <br />

        ただ、俺個人的には Flash じゃなくて AJAX やりたいわけだから、<br />
        1.の JSON が俺的ベスト。<br />
        <br />
      </li>

      <li>
        Response(サーバから返ってくるデータの形式)の選択肢:<br />
        <br />
        <ol>
          <li>JSON</li>
          <li>XML</li>
          <li>XHTML(部分)</li>
          <li>XHTML(全体:クライアントサイドのスクリプトを含む UI 一式)</li>
        </ol>
        <br />

        4.の XHTML(全体) というのは、AJAX, DHTML などの JavaScript コードを含む UI 全体である。<br />
        web1.0 時代には言うまでも無いことだったかもしれないが、<br />
        web2.0 時代ではクライアントに提供されるのはページ全体だけでは無いので、敢えて明記しておく。<br />
        <br />

        これ以外の、いわゆる AJAX でやりとりされるデータの形式として、<br />
        3.の XHTML(部分) はどうだろうか?(参考:<a href="http://microformats.org/wiki/rest/ahah" target="_blank">ahah</a>)<br />
        俺個人的には、(AJAX でない) DHTML も活用したいので、結局 JavaScript で DOM 操作すると思う。<br />
        HTML の動的な要素の管理はクライアントサイドにまとめたいので、<br />
        3.の XHTML(部分) は却下。<br />
        <br />
        Request と同様、2.の XML が最も web2.0 的だろうが、AJAX やるには JSON で充分。<br />
        <br />
        ということで、 web2.0 時代の AJAX なサーバは、<br />
        1.の JSON と、4.の XHTML(全体)をクライアントに提供するのが俺的ベスト。<br />
        <br />
      </li>

    </ul>

    <h4>ユーザインターフェイス</h4>
    <ul>

      <li>
        サーバサイド、クライアントサイドのテンプレートシステムの分担:<br />
        <br />
        <ol>

          <li>
            <dl>
              <dt>multi-page</dt>
              <dd>
                サーバサイドのテンプレートシステムは、<br />
                UI のバリエーションを広範囲に担当し、UI 上にコンテンツを展開する。<br />
                UI または、コンテンツを切替える際には、URL の遷移を伴う。<br />
                <br />
                クライアントサイドのテンプレートシステムは、<br />
                付加的要素のコンテンツ切替えだけを担当する。<br />
                この付加的要素のコンテンツを切替える際には URL は遷移しない( AJAX )。<br />
                DHTML も効果的に使う。<br />
                <br />
              </dd>
            </dl>
          </li>

          <li>
            <dl>
              <dt>single-page</dt>
              <dd>
                サーバサイドのテンプレートシステムは、<br />
                基本レイアウトだけを担当する。<br />
                URL の遷移は必要ない。<br />
                <br />
                クライアントサイドのテンプレートシステムは、<br />
                UI のバリエーションを広範囲に担当し、UI 上にコンテンツを展開する。<br />
                コンテンツを切替える際にも URL は遷移しない( AJAX )。<br />
                DHTML も効果的に使う。<br />
                <br />
              </dd>
            </dl>
          </li>

        </ol>
        <br />

        1.の multi-page が無難だが、2.の single-page も増えている。<br />
        (
        <a href="http://www.google.com/ig" target="_blank">google/ig</a>,
        <a href="http://www.live.com/" target="_blank">live.com</a>,
        <a href="http://www.netvibes.com/" target="_blank">netvibes</a>,
        <a href="http://ajax-pages.sourceforge.net/" target="_blank">ajax-pages</a>
        )
        <br />
        ただし、この場合 JavaScript のロードに工夫をしないと、最初の読み込みに相当の時間がかかる。<br />
        <br />
        multi-page で良いと思うが、<br />
        AJAX なアプリケーションの画面のうち使用頻度の高い画面は、<br />
        single-page 的に(つまり相当の機能をクライアントサイドで実装)したほうが、 AJAX 的ではある。<br />
        (参考: <a href="http://getahead.ltd.uk/ajax/single-page-design" target="_blank">AJAX: Single-page vs. Multi-page</a>)<br />
        <br />
      </li>

    </ul>

    <h4>結論</h4>

    整理してみると、つまり<br />
    「 <br />
    　1 画面(URL)毎の自由度が高くなったんだから、<br />
    　その自由度によっては、 1 画面(URL)毎の工数はベラボウにかかるかもしれないよ。<br />
    　慣れないうちは慎重に進行しようね。<br />
    　でも、その分、 画面(URL)数は減ると思うから、<br />
    　慣れれば、これまでと同じ工数でできるはず。<br />
    　だから頑張れって早く慣れろや。<br />
    」<br />
    という事だと納得した。<br />
    <br />
    じゃぁ…こういうフローで行こうかな。<br />
    <ol>

      <li>
        使用頻度の高い画面を選ぶ。<br />
        (クライアントサイドプログラマ・デザイナ)<br />
        <br />
      </li>

      <li>
        その画面の UI を設計する。<br />
        (クライアントサイドプログラマ・デザイナ)<br />
        <br />
        <ul>
          <li>
            その画面に必要な要素を絞り込む。
          </li>
          <li>
            要素を画面にレイアウトする。
          </li>
          <li>
            動的要素と静的要素に分ける。
          </li>
          <li>
            さらに AJAX が必要な要素を特定する。<br />
            <br />
          </li>
        </ul>
      </li>

      <li>
        AJAX の I/F を設計する。<br />
        (サーバサイドプログラマ・クライアントサイドプログラマ)<br />
        <br />
        <ul>
          <li>
            やりとりするデータの構造・および形式を決める。
          </li>
          <li>
            AJAX フレームワークを選定する。<br />
            <br />
          </li>
        </ul>
      </li>

      <li>
        AJAX の I/F を実装する。<br />
        (サーバサイドプログラマ・クライアントサイドプログラマ)<br />
        <br />
        <ul>
          <li>
            サーバサイドの AJAXified クラスの I/F を実装する。(ダミーで良い)
          </li>
          <li>
            クライアントサイド から AJAX してみる。<br />
            <br />
          </li>
        </ul>
      </li>

      <li>
        その画面の UI を実装する。<br />
        (サーバサイドプログラマ・クライアントサイドプログラマ・デザイナ)<br />
        <br />
        <ul>
          <li>
            サーバサイドのテンプレートシステムで、<br />
            UI の基本レイアウトの XHTML コードを作成する。
          </li>
          <li>
            クライアントサイドのテンプレートシステムで、<br />
            AJAX のレスポンス(JSON)を展開表示する。
          </li>
          <li>
            UI に効果的な DHTML を導入する。<br />
            <br />
          </li>
        </ul>
      </li>

      <li>
        サーバサイドのロジックを実装する。<br />
        (サーバサイドプログラマ)<br />
        <br />
        <ul>
          <li>
            AJAXified クラスの実装。<br />
            <br />
          </li>
        </ul>
      </li>

      <li>
        以上を 1画面作成の単位として、必要なだけ繰り返す。<br />
      </li>

    </ol>
    <br />
    まぁ、こんなところでしょう。<br />

  
]]></description>
<dc:date>2005-12-07T00:00:00+09:00</dc:date>
</item>
<item rdf:about="http://tonextone.com/note/diary/20051206.html">
<title>12/06 MVC2.0 その2</title>
<link>http://tonextone.com/note/diary/20051206.html</link>
<description><![CDATA[
web2.0 時代の Ajax なウェブアプリケーションにおけるMVC。<br />
「<a href="http://tonextone.com/note/diary/20051111.html">MVC2.0 その1</a>」の続き。<br />

    web2.0 時代の AJAX なウェブアプリケーションにおける MVC について。<br />

    <h4>良さげな AJAX ライブラリを比較</h4>
    <a href="http://pear.php.net/package/HTML_AJAX" targer="_blank">PEAR::HTML_AJAX</a> と
    <a href="http://www.xoad.org/" targer="_blank">XOAD</a> とを比較する。<br />

    HTML_AJAXは、昨日 0.3.1 が出たらしいので、
    <pre>$ pear install "channel://pear.php.net/HTML_AJAX-0.3.1"</pre>
    XOAD は普通に一式サーバにアップロードで OK 。

    <h4>共通点</h4>
    共通点を説明するために、勝手に用語を導入する。<br />
    <dl>
      <dt>
        AJAXify
      </dt>
      <dd>
        サーバサイドで定義されたクラスを AJAX 的に利用できるようにする事を「AJAXify」と呼ぶ。<br />
        HTML_AJAX, XOAD では、<br />
        サーバサイド(PHP)で定義されたクラスを<br />
        クライアントサイド(JavaScript)からコールする際に必要な、<br />
        クライアントサイドのコードを自動生成する機能を提供している(Sajax, JPSPANも同様)。<br />
        これを「AJAXify」ユーティリティと呼ぶ。<br />
        HTML_AJAX では、この機能の事を proxy と呼んでいるらしい。<br />
        HTML_AJAX の作者の blog '<a href="http://blog.joshuaeichorn.com/ajax-resources/library/?filter=provides:mapped_functions" target="_blank">There and Back Again</a>'では mapped_functions とか呼んでいる。<br />

      </dd>
    </dl>

    簡単なクラス( <a href="http://tonextone.com/test/xoad-0.6.0.0/examples/myTest/_String.class.phps ">_String.class.phps</a> )を AJAXify してみると、当然似たようなコードになる( <a href="http://tonextone.com/test/xoad-0.6.0.0/examples/myTest/diff.html">コードの比較</a> )。<br />

    動作デモはこちら。
    <a href="http://tonextone.com/test/PEAR/HTML_AJAX/test.php">HTML_AJAX</a>,
    <a href="http://tonextone.com/test/xoad-0.6.0.0/examples/myTest/test.php">XOAD</a>.<br />

    <h4>相違点</h4>

    <ol>
      <li>
        HTML_AJAX の「AJAXify」ユーティリティは、<br />
        クライアントサイドの「AJAXified」クラス(プロトタイプ)をサーバサイドで自動生成するので、<br />
        プログラマはこのクラスから「AJAXified」インスタンスを生成する JavaScript コードを書く。<br />
        この際、コンストラクタの引数としてコールバックオブジェクトのインスタンスを指定する。<br />
<pre>
&lt;script&gt;
var object = new _String(callBack);
var anotherObject = new _String(callBack);
&lt;/script&gt;
&lt;button onClick="object.returnFromPHP('JS&gt; how are you?\n')"&gt;click!&lt;/button&gt;
&lt;button onClick="anotherObject.returnFromPHP('JS&gt; again, how are you?\n')"&gt;click!&lt;/button&gt;
</pre>

        一方、XOAD の「AJAXify」ユーティリティは、<br />
        クライアントサイドの「AJAXified」インスタンスをサーバサイドで自動生成するので、<br />
        プログラマはインスタンスを生成する JavaScript コードを書かない。<br />
        その代わり、「AJAXified」インスタンスのメソッドの引数にコールバック関数を指定する。
<pre>
&lt;script&gt;
var object = &lt;?= XOAD_Client::register(new _String()) ?&gt;;
var anotherObject = &lt;?= XOAD_Client::register(new _String()) ?&gt;;
&lt;/script&gt;
&lt;button onClick="object.returnFromPHP('JS&gt; how are you?\n', callBack)"&gt;click!&lt;/button&gt;
&lt;button onClick="anotherObject.returnFromPHP('JS&gt; again, how are you?\n', callBack)"&gt;click!&lt;/button&gt;
</pre>
       <br />
      </li>

      <li>
        HTML_AJAX では、 server.php
<pre>
&lt;?
include_once('HTML/AJAX/Server.php');
$server = new HTML_AJAX_Server();
/*
 * 必要ならここでいろいろ設定。
 * でもどんな設定ができのか不明。
 */
$server->handleRequest();
?&gt;
</pre>
        とか言うのを作って置く必要があるが、<br />
        XOAD では不要。<br />
       <br />
      </li>

      <li>
        HTML_AJAX では、
<pre>
&lt;?
$ajax =& new HTML_AJAX();
$ajax->registerClass((new _String()),'_String',array('returnFromPHP'));
?&gt;
</pre>
        みたいに、クラス名、メソッド名のマッピングも「AJAXifiy」と同時にできる。<br />
        <br />
        一方、XOAD では、
<pre>
&lt;?
XOAD_Server::allowClasses('_String');
?&gt;
</pre>
        で済むんだけど、その代わり「AJAXify」したいクラスに、
<pre>
&lt;?
class _String
{
  /* snip */

  function xoadGetMeta()
  {
    XOAD_Client::mapMethods($this, array('returnFromPHP'));
    XOAD_Client::publicMethods($this, array('returnFromPHP'));
  }
}
?&gt;
</pre>
        みたいにメソッド名をマッピングするメソッドを追加する必要があり、ちょっとウザい。<br />
       <br />
      </li>

      <li>
        HTML_AJAX では、<br />
        XMLHTTPRequest で送信されるデータ、サーバから戻ってくるデータ共に、
<pre>
&lt;script&gt;
HTML_AJAX.defaultEncoding = 'JSON';
&lt;/script&gt;
</pre>
        で指定したエンコーディングが使われるらしい。<br />
        'JSON' 以外のオプションは 'NULL' って言うのがあるけど、それ以外は不明。<br />
        <br />
        一方、 XOAD では、<br />
        XMLHTTPRequest で送信されるデータは PHP の <a href="http://jp2.php.net/serialize" target="_blank">serialize();</a> 形式、<br />
        サーバから戻ってくるデータは JSON。<br />
        POST を監視するとこんなのがサーバに飛んできました。
<pre>
a:4:{s:6:"source";s:18:"O:7:"_string":0:{}"; \
     s:9:"className";s:7:"_string";s:6:"method";s:13:"returnFromPHP"; \
     s:9:"arguments";s:35:"a:1:{i:0;s:17:"JS> how are you?";}";}
</pre>
        JavaScript で、 XOAD.serialize(); している。<br />
        お互いに相手に合わせてる感じ(笑)。良いのか悪いのか。<br />
       <br />
      </li>
      <li>
        ちなみに、クライアントライブラリとして読み込まれる JavaScript の行数は、<br />
        HTML_AJAX : 2681<br />
        XOAD : 611<br />
       <br />
      </li>
    </ol>

    <h4>考察</h4>
    疲れたので、一服してから別エントリとして。<br />
    <br />

    <h4>参考URL</h4>
    [HTML_AJAX]<br />
    <a href="http://blog.joshuaeichorn.com/slides/Introduction-To-HTML_AJAX/" target="_blank"> HTML_AJAX 作者の方によるスライド</a><br />
    <a href="http://blog.joshuaeichorn.com/archives/category/php/html_ajax/" target="_blank"> HTML_AJAX 作者の方の関連記事</a><br />
    <a href="http://bluga.net/projects/HTML_AJAX/examples/" target="_blank">多分同じ人によるexamples</a><br />
    <br />
    [XOAD]<br />
    <a href="http://www.xoad.org/examples/" target="_blank">公式ページ</a><br />

  
]]></description>
<dc:date>2005-12-06T21:00:00+09:00</dc:date>
</item>
<item rdf:about="http://tonextone.com/note/diary/20051204.html">
<title>12/04 PEAR その2</title>
<link>http://tonextone.com/note/diary/20051204.html</link>
<description><![CDATA[
PEAR で遊んでみる。<br />
「<a href="http://tonextone.com/note/diary/20051127.html">PEAR その1</a>」の続き。<br />

    <h4>web1.0 系</h4>
    <ol>
      <li>Auth は「帯に短し」。</li>
      <li>Mail_Mime は普通に使える。</li>
    </ol>

    <h4>web2.0 系</h4>
    <ol>
      <li>
        HTTP_Request は個人プロジェクト(<a href="/sparQuery/" target="_blank">sparQuery</a>)などで使っている。<br />
        HTTP_Client より API の抽象化レベルが低いので、そのぶん強力。<br />
        これからも使うだろう。<br />
      </li>
      <li>
        XML_Serializer も上記プロジェクトなどで使っている。<br />
        XML_RSS より API の抽象化レベルが低いので、そのぶん強力。<br />
        これからも使うだろう。<br />
      </li>
      <li>
        XML_RPC はこれからも自発的には使わないだろう(SOAP も同様)。<br />
        サーバ間通信は REST でお願いします。
      </li>
      <li>
        HTML_AJAX は思ったより良さそう。<br />
        クライアントサイドから呼び出すクラスを登録(HTML_AJAX::registerClass(new SomeClass());)しておけば、
        <pre>&lt;script&gt;HTML_AJAX.call(SomeClass, someMethod, callBackFunc, arg1, arg2, ...);&lt;/script&gt;</pre>
        とするだけで、サーバサイドの
        <pre>&lt;? SomeClass::someMethod($args); ?&gt;</pre>
        を呼び出せる。<br />
        こういうのを RPC とか mapped-function とか言うのだと思っている。<br />
        上記プロジェクトでは <a href="http://www.modernmethod.com/sajax/" target="_blank">Sajax</a> を使っているが、基本的に同様のものだ。<a href="http://jpspan.sourceforge.net/wiki/doku.php" target="_blank">JPSPAN</a> も同様。<br />
        ただ、Sajax も JPSPAN も、開発が停滞しており、<br />
        HTML_AJAX と <a href="http://www.xoad.org/" target="_blank">XOAD</a>とを、後継候補として検討中。
      </li>
    </ol>

    明日は、「MVC2.0 その2」として HTML_AJAX と XOAD との試用レポートを書く予定。

  
]]></description>
<dc:date>2005-12-04T00:00:00+09:00</dc:date>
</item>
<item rdf:about="http://tonextone.com/note/diary/20051127.html">
<title>11/27 PEAR その1</title>
<link>http://tonextone.com/note/diary/20051127.html</link>
<description><![CDATA[
PEAR で遊んでみる。<br />
PEAR との付き合い方を探っている。<br />
    これまで使った事があるもの:<br />
    <ol>
      <li>
        誰が作っても同じ API になりそうな比較的堅いもの。<br />
        ( HTTP_Request など)
      </li>
      <li>
        自作するには労力がかかりすぎるもの。<br />
        ( XML_Serializer など)
      </li>
    </ol>
    つまり、いろんな意味でブラックボックスとして扱いたい単機能は PEAR で充分。<br />
    逆に、開発のモチベーションに直結する機能、ブラックボックスでは困る機能に関しては、<br />
    自作ライブラリを使って来た…と言える。今にして思えば。<br />
    <br />
    大きめの開発の立ち上がりは、いつもライブラリ/フレームワークの設計から始めていた。<br />
    フレームワークの開発自体に面白味を感じていたからこそ、そういうスタイルでやって来たわけで、<br />
    それが今では自分の力になっている。<br />
    一人で開発・メンテナンスするなら、それで良いと思う。<br />
    <br />
    ただ、これからは、いろいろとオープンにしたいので、<br />
    まぁ共通語としての PEAR を読み書きくらいは出来るように勉強中。<br/ >

    <h4>今日のメモ:</h4>
    <ol>
      <li>
        PEAR に channel:// という概念が導入され、<br />
        レポジトリを切替えてパッケージ管理できるように?なったらしい。<br />
        <pre>$ pear config-show;</pre>
        してみると、デフォルトの channel なんかが見れる。
        <pre>$ pear upgrade 'channel://pear.php.net/XML_Serializer-0.18.0';</pre>
        とか使う。
      </li>
      <li>
        DB は抽象化クラス。<br />
        DB_DataObject は O/R マッパークラス。<br />
        基本的な部分しか試してないけど、分かりやすい。<br />
        O/R マッピングってこういうことか…。<br />
        O/R マッパーじゃないけど似たような使い勝手のライブラリ<br />
        (非オブジェクト指向)を自作してあるので早くも興ざめ。<br />
      </li>
    </ol>

    次は、Auth, Mail_Mime を。<br />
    さらにその後は web2.0 な、 HTTP_Request, XML_Serializer, XML_RPC, HTML_AJAX で遊ぶ予定。
  
]]></description>
<dc:date>2005-11-27T00:00:00+09:00</dc:date>
</item>

</rdf:RDF>

