Ajaxなタブエディタ(データ転送にはJSONを使用)
今回サンプルで作成するアプリケーションは、Web上で書き換え可能なタブエディタを作成します。作成イメージはこちらになります。
ここで作成するアプリケーションでは、サーバから送信されるデータの形式にJSONを利用します。最近のWebアプリケーションではよくこの形式が使われます。S2Dao.PHP5では、このJSON形式でデータベースの値を取得することができるので、それを利用します。
最近のPHP5.2.0ではデフォルトでPHP上からJSONフォーマットに変換する拡張モジュールが利用できるようになっています。
また、S2Dao.PHP5ではデータベースからの結果セットをJSONで取得することが可能なので、今回はこの機能を利用しています。
部品の作成(1/2)
モジュールの作成
先ほど作成した「codezine」のディレクトリ内で、コンソール上からphingコマンドを実行し、モジュールの作成を行います。今回、モジュール名は「tabedit」とします。
> phing
:
: (省略)
:
[ Command list ]
0 : (exit)
1 : action
2 : command
3 : dao
4 : dicon
5 : entity
6 : goya
7 : interceptor
8 : module
9 : service
choice ? : 8
module name ? : tabedit
[ generate information ]
module name : tabedit
confirm ? (y/n) : y
[INFO ] create : /home/hata/workspace/codezine/app/modules/tabedit
[INFO ] create : /home/hata/workspace/codezine/app/modules/tabedit/
action/
[INFO ] create : /home/hata/workspace/codezine/app/modules/tabedit/dao/
:
: (省略)
:
[ Command list ]
0 : (exit)
1 : action
2 : command
3 : dao
4 : dicon
5 : entity
6 : goya
7 : interceptor
8 : module
9 : service
choice ? : 0
BUILD FINISHED
モジュールを作成すると「app/modules/」以下にディレクトリが作成されます。
app/modules/tabedit/ |-- action |-- dao |-- dicon |-- entity |-- interceptor |-- service |-- tabedit.inc.php `-- view
これから作成するActionクラスやServiceクラスはこのモジュール(「tabedit」)の配下で作成していきます。S2Base.PHP5ではモジュール単位での開発をサポートしており、モジュール単位に同じディレクトリが生成されます。

また、今回のモジュールではレイヤーパターンに置き換えると次のようなイメージになります。

それでは、モジュールの作成も完了したので、アプリケーションで必要なプログラムの雛型を生成していきます。基本的に、生成される雛型を修正しながら開発を行います。
データベースへのアクセス
データベースにアクセスするためにはDaoコマンドでDaoインターフェイスを作成し、ServiceコマンドでServiceクラスを生成してから、Actionクラスにinjectすることになります。テーブル定義としては次のようなものを想定して作成しました。
CREATE TABLE Tab ( id integer not null, title varchar(200) not null, content text, primary key(id) );
この定義体を元にDaoコマンドでインターフェイスを作成します。以下、phing実行時に選択した画面です。
[ Command list ] 0 : (exit) 1 : action 2 : command 3 : dao 4 : dicon 5 : entity 6 : goya 7 : interceptor 8 : module 9 : service choice ? : 3 [ Module list ] 0 : (exit) 1 : tabedit choice ? : 1 dao interface name ? : TabDao entity class name ? [TabEntity] : table name ? [TAB] : Tab columns ? (id,name,--,,) : id, title, content [ generate information ] module name : tabedit dao interface name : TabDao dao test class name : TabDaoTest entity class name : TabEntity entity class extends : none table name : Tab columns : id, title, content dao dicon file name : TabDao.dicon confirm ? (y/n) : y [INFO ] create : /home/hata/workspace/codezine/app/modules/tabedit/dao/TabDao.class.php [INFO ] create : /home/hata/workspace/codezine/test/modules/tabedit
/dao/TabDaoTest.class.php [INFO ] create : /home/hata/workspace/codezine/app/modules/tabedit/
dicon/TabDao.dicon [INFO ] create : /home/hata/workspace/codezine/app/modules/tabedit/
entity/TabEntity.class.php
次に、serviceコマンドからServiceクラスを作成し、作成したDaoインターフェイスをinjectします。
[ Command list ] 0 : (exit) 1 : action 2 : command 3 : dao 4 : dicon 5 : entity 6 : goya 7 : interceptor 8 : module 9 : service choice ? : 9 [ Module list ] 0 : (exit) 1 : tabedit choice ? : 1 service interface name ? : TabEditService service class name ? [TabEditServiceImpl] : [ generate information ] module name : tabedit service interface name : TabEditService service class name : TabEditServiceImpl service test class name : TabEditServiceImplTest service dicon file name : TabEditServiceImpl.dicon confirm ? (y/n) : y [INFO ] create : /home/hata/workspace/codezine/app/modules/tabedit/service/TabEditServiceImpl.class.php [INFO ] create : /home/hata/workspace/codezine/app/modules/tabedit/
service/TabEditService.class.php [INFO ] create : /home/hata/workspace/codezine/test/modules/tabedit
/service/TabEditServiceImplTest.class.php [INFO ] create : /home/hata/workspace/codezine/app/modules/tabedit/
dicon/TabEditServiceImpl.dicon
ここで、生成されたTabEditServiceインターフェイスとTabEditServiceImpl、TabDaoインターフェイスを修正していきます。
TabEditServiceは次のように修正しました。
<?php interface TabEditService { public function getAll(); public function find($tabId); public function add(TabEntity $entity); public function update(TabEntity $entity); public function delete(TabEntity $entity); } ?>
Serviceクラスは各アクションで参照されることになりますので、分かりやすい命名とそのServiceクラスに適したメソッドを用意します。
次にTabDaoインターフェイスを次のように修正しました。
<?php interface TabDao { const BEAN = "TabEntity"; const findAllJson_QUERY = "order by id"; public function findAllJson(); const getTabJson_QUERY = "id = /*id*/1"; public function getTabJson($id); public function update(TabEntity $entity); public function insert(TabEntity $entity); public function delete(TabEntity $entity); } ?>
大部分のメソッドは生成時に作られているものをそのまま使用することができます。その他必要になった部分だけを修正するだけで問題ありません。今はまだ触れませんが、S2Dao.PHP5においてメソッド名によって結果セットを変更できる機能があるので、既にここで指定しています。
次は、TabEditServiceImplをこのインターフェイスが提供する通りに実装し、Daoを受け取るためにsetterを用意します。
<?php class TabEditServiceImpl implements TabEditService{ private $dao; public function __construct(){} // typehintでinjectしたいDaoインターフェイス(TabDao)を // 指定しています。 public function setDao(TabDao $dao){ $this->dao = $dao; } public function getAll(){ return $this->dao->findAllJson(); } public function find($tabId){ return $this->dao->getTabJson($tabId); } public function add(TabEntity $entity){ return $this->dao->insert($entity); } public function update(TabEntity $entity){ return $this->dao->update($entity); } public function delete(TabEntity $entity){ return $this->dao->delete($entity); } } ?>

action/
[INFO ] create : /home/hata/workspace/codezine/app/modules/tabedit/dao/
:
: (省略)
:
[ Command list ]
0 : (exit)
1 : action
2 : command
3 : dao
4 : dicon
5 : entity
6 : goya
7 : interceptor
8 : module
9 : service
choice ? : 0
BUILD FINISHED