tonextone.com/note/

Last-modified: 2006-09-01 (金)

Copyright ©master_at_tonextone.com All rights reserved.

PostgreSQL で RDB 設計 その2

Posted : 2005-12-23 00:00 / Category : [開発日誌]
PostgreSQL で RDB 設計 その1」の補足。
PostgreSQL では、WHERE 句に、正規表現が使えるので、いつも重宝している。
こんな感じ。
  • 使用前:
    select * from some_table where some_field = 1 or some_field = 4 or ... ;
    
  • 使用後:
    select * from some_table where some_field ~ '^(1|4|...)$';
    
で、配列型のフィールド 'some_array' に対しても、
ANY(some_array) をカマせば、これができるだろうと期待していた。

いろいろ試したが、どうも無理っぽい[マニュアルより ANY/SOME(array)]。

そういう目的では、
配列型ではなく TEXT 型とかに配列表現を突っ込むのが良いだろう。
とりあえず TEXT 型で用意しておいて、記法は充分検討してゆっくり決めれば良い。

例えば、PHP の serialize(); の場合、数値配列は、
a:2:{i:0;i:123;i:1;i:456;}
という感じで、キーと値とが交互に表れるが、
このキーと値との選り分けを正規表現なんかでやってられない。
そうなると独自記法がベストな気がしてきた( JSON とか XML とかも無意味に面倒)。

正規表現のメタキャラクタとして解釈されなくて、
尚且つ、データに使われなさそうな文字列を、セパレータにすれば良い。
クォーテーションの扱いにも注意。

以下、例:
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

ツッコミ

1: jrgrpmhu (07/25 23:48) jrgrpmhu
<a href="http://jkdrbkij.com">jqgojfus</a> [URL=http://kuussydq.com]iquwdonv[/URL] qchjdqux http://uqxzqlta.com jgnoijpy mzibspho
[ このエントリへはツッコミ出来ません ]

PostgreSQL で RDB 設計 その1

Posted : 2005-12-22 02:00 / Category : [開発日誌]
4 年くらい前から PostgreSQL を使っている。
MySQL は、システム上必要な場合以外は使っていない。

MySQL が嫌いなわけではなく、
「何かみんな MySQL だなぁ…俺も MySQLer になろうかなぁ。」
と思ったことは数知れず。

でも、PostgreSQL にしかない機能の恩恵に、度々、与ってしまっているので、「乗り換え」には至らず。

それにしても、いろいろな RDBMS があるものだ ( RDBMS比較資料[PDFです] )。

各 RDBMS の特徴は、DB の設計や、チューニングの際に、顕著になるのではないだろうか?
「管理しやすくて、検索が速くて、更新もサクサクできる」
そんな DB はどうしたら実現できるだろうか…と考えていくと、自然と実装の話になっていく。
(もちろん DB を抽象化してポータブルに作っておく事が要求される場合は別。)

ということで、前置きが長くなったが、 PostgreSQL でいろいろ試したメモ。

データのセグメンテーション

PostgreSQL のデータは、
cluster ⊃ database ⊃ schema ⊃ table
という階層の最下層であるところの 'table' に保存されるが、
これらの各階層で権限の設定ができる。

「複数ユーザ(100 アカウント程度)を想定した場合、どの階層で分断するのが現実的か?」
というのを、改めてマジメに考えてみた。

以下、 アカウント [user] のデータ識別子を [user] とする。
  1. table :
    => create table [user]_table(...);
    => grant all on [user]_table to [user];
    
    却下
    (テーブルの一覧がすごい事になるため)。

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

  3. database :
    $ createdb [user];
    $ createuser -P [user];
    
    採用
    (もっとも現実的)

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

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

選択型データの保存形式

例えば、

好きな果物はなんですか?
A. りんご
B. みかん
C. いちご
...
P. いちじく

という問いに対する回答を保存したい場合、
  1. RAW: 'りんご'とか'いちご'という内容を保存すべきか?
  2. CODE: 'A'とか'C'というコードを保存すべきか?

◆RAW に対する CODE の strong / weak points :

[管理系]
O コードと内容との対応を外部で一元管理できるので修正が容易。
X コードと内容との対応表が無いとデータとして成立しない。

[検索系]
O データが簡潔に表せるのでちょっと速いかも。
X 特になし。

[更新系]
O 特になし。
X 特になし。

管理系の視点で CODE のほうが有利と判断する。
これも「正規化」に通じる当たり前の結論。
ただし、コードと内容との対応表(マスターテーブル) の死守が前提。

データ構造の保存

例えば、
members =
[
    {
      'name': '太郎',
      'gender': '男'
      'fruits': [1, 3]
    },

    {
      'name': '花子',
      'gender': '女'
      'fruits': [2, 3, 11]
    }
];
というデータ構造を保存したい場合、
  1. NORMAL:
    データの値 1 つをフィールド 1 つに( 1 対 1 に)保存するべきか?
    上の例の場合、正規化後のテーブルは 3 つか 4 つになるはず。

  2. BULK:
    上の例(意図的に JSON で記述してある)のように、
    「データのラベルや値を含む構造そのものを適切に表現する文字列」
    として保存するべきか?

BULK の例としては、JSON の他に、
PHPコードそのもの( array('name'=>'太郎',...) )、
それを serialize(); したもの、あるいは、XML などを想定している。
また、少し毛色が違うが、PostgreSQL の配列型データも、BULK の一種として考える。

◆NORMAL に対する BULK の strong / weak points :

[管理系]
O データ構造とテーブル定義の結合度が低いので、より汎用性がある。
X データを直接操作しにくい ?
  => PostgreSQL の配列型では問題無し。

[検索系]
O 主テーブルを検索するだけで、該当するデータ構造を取得できる。
X 直積を作りにくい ?
  => PostgreSQL の配列型では問題無し。

[更新系]
O 主テーブルを更新するだけで、該当するデータ構造を更新できる。
X データ構造の部分的な更新がしにくい ?
  => PostgreSQL の配列型では問題無し。

総合的に視て、BULK というか「 PostgreSQL の配列型」のほうが有利と判断する。

以下、具体例
  1. NORMAL の場合:
    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
    
  2. BULK の場合:
    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
    

感想

たまにマニュアルを読むと幸せになれる…と信じよう。

ツッコミ

1: master (12/22 12:27)
PostgreSQL 7.4 で、配列型の関数などが一気に増えたようで、

where ':' || array_to_string(some_array,':') || ':' ~ ':(1|2):'

なんて事もできる。

バージョンも気にしないと。
http://www.postgresql.org/docs/current/static/release-7-4#AEN76154
[ このエントリへはツッコミ出来ません ]

サーバ管理その1

Posted : 2005-12-13 04:00 / Category : [開発日誌/server]
tf-idf + bayesian-filter を試したいので、このサーバに chasen とか mecab とか入れる事にした。
で、かなり放置していたので、いろいろと整備した。
以下、メモ:

ports

packageはコンパイル済だが、ports は未コンパイル。その分、強力。
ports の実体はスケルトン。↓こんな感じ。
$ 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

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

$ # ports のデータベースを更新する。
$ portsdb --update --fetchindex;  # index は配布されているものを使う。
$ # または、
$ portsdb --update --updateindex; # index も構築する。
$ # または、
$ cd /usr/ports/; make index; # より確実らしい。

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

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

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

$ # ports の作業ファイルを削除する。distclean は 2 回指定する。
$ portsclean --workclean --distclean --distclean;

portinstall / portupgrade の再に現れる CUI で、大抵の config オプションを設定できる。
( ports で管理できる config オプションを 'knob' と呼ぶらしい。)

設定を変えて再インストールしたい場合とかは、
$ まず消す。
$ cd /usr/ports/foo/bar;
$ make deinstall;

$ # config の CUI を使えるかもしれない。
$ make config;

# # CUI 使えたら、
$ make reinstall;

# # CUI 使えなかったら、
$ # /usr/local/etc/pkgtools.conf の MAKE_ARGS にオプションを指定して、
$ portinstall --verbose foo/bar ;

今回は、先ず、いろいろアップグレードした。
$ portupgrade --interactive --all;
$ portsclean --workclean --distclean --distclean;

それから、無くて困っていた screen をインストールした。
FreeBSD Portsで cvs から 'screen' を検索して、それが /usr/ports の下にあることを確認して、
$ portinstall --verbose sysutils/screen;
$ portsclean --workclean --distclean --distclean;
簡単。

参考:
  1. アプリケーションのインストール - packages と ports
  2. portupgrade

src からインストール

APP(ApachePostgresqlPhp) は、 src で管理している。
これも、ついでにアップグレード。
(apache-1.3.34 も出ているが、これは Apache-SSL が出るまで待つことにした。)
  • postgresql-8.1.1
  • php-4.4.1
  • ZendOptimizer-2.6.0
  • php-json-ext-1.1.0
PostgreSQL の migration も、

[backup]
pg_dumpall -g > /home/postgres/backup/all.dmp;
pg_dump -b -F c foo > /home/postgres/backup/foo.dmp;
[restore]
psql -f all.dmp template1
pg_restore -d foo foo.dmp
で、無事完了。

参考:
  1. PHP 4.4.1. Release Announcement
  2. PostgreSQL 8.1.0 Documentation

ハマりどころ

最近 PHP のリリースが安定していないので、必要以上にビビっていたせいもあり、
実は結構ハマった。
  1. $ pkgdb -F;
    このサーバの構築に際して、上記 APP などを src で管理するために、
    VPS7 の標準構成から package/ports 版をアンインストールして頂いた。
    その際、PHP の拡張(php4-xxx) の package/ports が取り残されていたらしく、
    存在しない apache との依存関係を引きずっているようだった。
    とりあえず、
    $ pkgdb -F;
    
    したら問題無さそう。

  2. autoconf,automake,libtool の重複
    ひとしきり portupgrade/portsclean して、
    $ portversion --verbose;
    
    してみたら、autoconf,automake,libtool がバージョン違いで複数ある。
    不安に思いつつ、PHP を src からインストールする作業に取り掛かると、
    configure で warning が出て、make も失敗。
    *** 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.
    
    package/ports のツリーがイカレたか?
    と思ったが、重複自体は問題ないらしい。
    package/ports 間の依存関係の連鎖を最小限にするために、
    被依存バージョンを残しつつ、別のバージョンもインストールする方針らしい。
    とりあえず、libtool とかが見つからないのはマズい気がしてタマらなかったので、
    $ ln -s /usr/local/bin/libtool15 /usr/local/bin/libtool
    
    とか、しばらくゴニョゴニョやってたら、なんかコンパイルできた。
    途中、不安が不安を呼んで、
    config.log の fail とか warn とかの多さにくじけそうになったが、
    もともと config.log は、そういうものらしいし、とりあえず動いてるのでヨシ。

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

トラックバック

(1)

ツッコミ

1: master (12/16 17:56)
その後、PECL の filter を入れようとしたら、make でこけた。
PHP 変わり過ぎ。
拡張で提供されるはずの関数の API 真似て、関数を自作しといて、
安定したら乗り換えるとか…無謀か。
2: master (12/17 14:19)
ちなみに、PRCL の chasen はコンパイルできたんだけど、
使うとセグメンテーションエラーで落ちる。
しかたないので、システム関数で呼んでおきます。
[ このエントリへはツッコミ出来ません ]

MVC2.0 その3

Posted : 2005-12-07 00:00 / Category : [開発日誌]
MVC2.0 その2」の続き。
web2.0 時代の AJAX なウェブアプリケーションにおける MVC について。

AJAX するデータの形式

  • Request(サーバへ送信されるデータの形式)の選択肢:

    1. JSON
    2. XML
    3. PHP/serialize(など、サーバサイド言語固有のデータ記法)

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

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

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

  • Response(サーバから返ってくるデータの形式)の選択肢:

    1. JSON
    2. XML
    3. XHTML(部分)
    4. XHTML(全体:クライアントサイドのスクリプトを含む UI 一式)

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

    これ以外の、いわゆる AJAX でやりとりされるデータの形式として、
    3.の XHTML(部分) はどうだろうか?(参考:ahah)
    俺個人的には、(AJAX でない) DHTML も活用したいので、結局 JavaScript で DOM 操作すると思う。
    HTML の動的な要素の管理はクライアントサイドにまとめたいので、
    3.の XHTML(部分) は却下。

    Request と同様、2.の XML が最も web2.0 的だろうが、AJAX やるには JSON で充分。

    ということで、 web2.0 時代の AJAX なサーバは、
    1.の JSON と、4.の XHTML(全体)をクライアントに提供するのが俺的ベスト。

ユーザインターフェイス

  • サーバサイド、クライアントサイドのテンプレートシステムの分担:

    1. multi-page
      サーバサイドのテンプレートシステムは、
      UI のバリエーションを広範囲に担当し、UI 上にコンテンツを展開する。
      UI または、コンテンツを切替える際には、URL の遷移を伴う。

      クライアントサイドのテンプレートシステムは、
      付加的要素のコンテンツ切替えだけを担当する。
      この付加的要素のコンテンツを切替える際には URL は遷移しない( AJAX )。
      DHTML も効果的に使う。

    2. single-page
      サーバサイドのテンプレートシステムは、
      基本レイアウトだけを担当する。
      URL の遷移は必要ない。

      クライアントサイドのテンプレートシステムは、
      UI のバリエーションを広範囲に担当し、UI 上にコンテンツを展開する。
      コンテンツを切替える際にも URL は遷移しない( AJAX )。
      DHTML も効果的に使う。


    1.の multi-page が無難だが、2.の single-page も増えている。
    ( google/ig, live.com, netvibes, ajax-pages )
    ただし、この場合 JavaScript のロードに工夫をしないと、最初の読み込みに相当の時間がかかる。

    multi-page で良いと思うが、
    AJAX なアプリケーションの画面のうち使用頻度の高い画面は、
    single-page 的に(つまり相当の機能をクライアントサイドで実装)したほうが、 AJAX 的ではある。
    (参考: AJAX: Single-page vs. Multi-page)

結論

整理してみると、つまり

 1 画面(URL)毎の自由度が高くなったんだから、
 その自由度によっては、 1 画面(URL)毎の工数はベラボウにかかるかもしれないよ。
 慣れないうちは慎重に進行しようね。
 でも、その分、 画面(URL)数は減ると思うから、
 慣れれば、これまでと同じ工数でできるはず。
 だから頑張れって早く慣れろや。

という事だと納得した。

じゃぁ…こういうフローで行こうかな。
  1. 使用頻度の高い画面を選ぶ。
    (クライアントサイドプログラマ・デザイナ)

  2. その画面の UI を設計する。
    (クライアントサイドプログラマ・デザイナ)

    • その画面に必要な要素を絞り込む。
    • 要素を画面にレイアウトする。
    • 動的要素と静的要素に分ける。
    • さらに AJAX が必要な要素を特定する。

  3. AJAX の I/F を設計する。
    (サーバサイドプログラマ・クライアントサイドプログラマ)

    • やりとりするデータの構造・および形式を決める。
    • AJAX フレームワークを選定する。

  4. AJAX の I/F を実装する。
    (サーバサイドプログラマ・クライアントサイドプログラマ)

    • サーバサイドの AJAXified クラスの I/F を実装する。(ダミーで良い)
    • クライアントサイド から AJAX してみる。

  5. その画面の UI を実装する。
    (サーバサイドプログラマ・クライアントサイドプログラマ・デザイナ)

    • サーバサイドのテンプレートシステムで、
      UI の基本レイアウトの XHTML コードを作成する。
    • クライアントサイドのテンプレートシステムで、
      AJAX のレスポンス(JSON)を展開表示する。
    • UI に効果的な DHTML を導入する。

  6. サーバサイドのロジックを実装する。
    (サーバサイドプログラマ)

    • AJAXified クラスの実装。

  7. 以上を 1画面作成の単位として、必要なだけ繰り返す。

まぁ、こんなところでしょう。

トラックバック

(3)
[ このエントリへはツッコミ出来ません ]

MVC2.0 その2

Posted : 2005-12-06 21:00 / Category : [開発日誌]
MVC2.0 その1」の続き。
web2.0 時代の AJAX なウェブアプリケーションにおける MVC について。

良さげな AJAX ライブラリを比較

PEAR::HTML_AJAXXOAD とを比較する。
HTML_AJAXは、昨日 0.3.1 が出たらしいので、
$ pear install "channel://pear.php.net/HTML_AJAX-0.3.1"
XOAD は普通に一式サーバにアップロードで OK 。

共通点

共通点を説明するために、勝手に用語を導入する。
AJAXify
サーバサイドで定義されたクラスを AJAX 的に利用できるようにする事を「AJAXify」と呼ぶ。
HTML_AJAX, XOAD では、
サーバサイド(PHP)で定義されたクラスを
クライアントサイド(JavaScript)からコールする際に必要な、
クライアントサイドのコードを自動生成する機能を提供している(Sajax, JPSPANも同様)。
これを「AJAXify」ユーティリティと呼ぶ。
HTML_AJAX では、この機能の事を proxy と呼んでいるらしい。
HTML_AJAX の作者の blog 'There and Back Again'では mapped_functions とか呼んでいる。
簡単なクラス( _String.class.phps )を AJAXify してみると、当然似たようなコードになる( コードの比較 )。
動作デモはこちら。 HTML_AJAX, XOAD.

相違点

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

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

  3. HTML_AJAX では、
    <?
    $ajax =& new HTML_AJAX();
    $ajax->registerClass((new _String()),'_String',array('returnFromPHP'));
    ?>
    
    みたいに、クラス名、メソッド名のマッピングも「AJAXifiy」と同時にできる。

    一方、XOAD では、
    <?
    XOAD_Server::allowClasses('_String');
    ?>
    
    で済むんだけど、その代わり「AJAXify」したいクラスに、
    <?
    class _String
    {
      /* snip */
    
      function xoadGetMeta()
      {
        XOAD_Client::mapMethods($this, array('returnFromPHP'));
        XOAD_Client::publicMethods($this, array('returnFromPHP'));
      }
    }
    ?>
    
    みたいにメソッド名をマッピングするメソッドを追加する必要があり、ちょっとウザい。

  4. HTML_AJAX では、
    XMLHTTPRequest で送信されるデータ、サーバから戻ってくるデータ共に、
    <script>
    HTML_AJAX.defaultEncoding = 'JSON';
    </script>
    
    で指定したエンコーディングが使われるらしい。
    'JSON' 以外のオプションは 'NULL' って言うのがあるけど、それ以外は不明。

    一方、 XOAD では、
    XMLHTTPRequest で送信されるデータは PHP の serialize(); 形式、
    サーバから戻ってくるデータは JSON。
    POST を監視するとこんなのがサーバに飛んできました。
    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?";}";}
    
    JavaScript で、 XOAD.serialize(); している。
    お互いに相手に合わせてる感じ(笑)。良いのか悪いのか。

  5. ちなみに、クライアントライブラリとして読み込まれる JavaScript の行数は、
    HTML_AJAX : 2681
    XOAD : 611

考察

疲れたので、一服してから別エントリとして。

参考URL

[HTML_AJAX]
HTML_AJAX 作者の方によるスライド
HTML_AJAX 作者の方の関連記事
多分同じ人によるexamples

[XOAD]
公式ページ

トラックバック

(2)

ツッコミ

1: master (12/12 12:33)
HTML_AJAX, XOAD ともに、JSON を PHP のデータとして自動展開するが、
その際、PHP のオブジェクトとして展開する。
これを連想配列として展開するように変更するためのクラスメンバがない。
XMLHttpRequest の POST/GET を切替えるためのメンバもない。
結局、この辺が分かりやすい Sajax はかなり使える。
[ このエントリへはツッコミ出来ません ]