[Seasar-php 90] Seaserのcomponent定義について

ISITOYA Kentaro isitoya
2005年 10月 24日 (月) 15:49:01 JST


石戸谷と申します。
よろしくお願いします。

先日、ようやく重い腰を上げてs2container.PHP5を使ってみました。
Hogeインターフェース、HogeImplクラス、Hoge.diconファイル、HogeClientを用
意して実験をしたのですが、実行したときに、SeaserにReflectionExceptionと
いわれてしまいました。
そのソースは以下です。

HogeClient.php
<?php
require_once(dirname(__FILE__) . "/../../../../s2container.inc.php");
//require_once("./HogeImpl.class.php");
$container = S2ContainerFactory::create("Hoge.dicon");
$hoge = $container->getComponent('Hoge');
$hoge->hoge();
?>

Hoge.dicon
<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN"
"components21.dtd">
<components>
<component name="Hoge" class="HogeImpl">
</component>
</components>

HogeClient.phpのrequire_once("./HogeImpl.class.php");のコメントをはずせ
ばこのクライアントは期待通りの動作をします。これは、
src/s2container.php5/org/seasar/framework/container/impl/ComponentImpl.class.php
の実装に依存するもので、constractor内の最初の処理、51-53行目
if($componentClass!=""){
$this->componentClass_ = new ReflectionClass($componentClass);
}
という実装による物だと思います。
これだと、S2Container.PHP5を通じて利用したい・するであろう・しないかもし
れない・しないクラスを、createメソッドが呼ばれる直前にロードしなければな
りません。せっかく実装から分離できるはずなのにこれではちょっと格好よくな
い気がするのですが、なにかしら、対応をする予定はあるでしょうか。

解決法を何となく考えてみると、
・ReflectionClassの前にファイルのロードをしてくれるロジックを挿入する
私たちが利用しているクラスローダーのURLです。
http://soya.guarana.cc/trac/guarana/ja/file/core/trunk/core/src/php/util/ClassLoader.php
例えば。
$classname = "repository.handler.Soya_KaibashiraRepositoryHandler";
Util_ClassLoader::import($classname);
$container->create($classname);

・コンポーネントタグに対象のファイル名をかけるようにする
<component name="hoge" classname="HogeImpl" filename="./HogeImpl.class.php">
</component>

・無理矢理
<component name="init">
require_once('ClassA.class.php');
return new Exception(); // クラスは何でも
</component>
<component name="hoge">
//ここでrequireしても動かず。
new Hoge();
</component>

$contaner->getComponent("init");
$hoge = $container->getComponent("hoge");
$hoge->hoge();

などなど。

Javaだと、クラス名をフルネームで渡せば良いのでラクチンですが、クラス名に
対応したファイル名をつけなければならないという制約がないので、面倒くさい
ことになっているのだと思います。
実際、私たちが開発しているソフトウェアの場合Hogeというクラスを作りたいと
して、Hogeという名前だと名前空間がないためにそのままではバッティングする
可能性があります。そこで、Soyaというプレフィックスをつけてクラスを定義す
るというルールを作っています。HogeならSoya_Hoge です。でも、ファイル名は
Hoge.phpです。
PHPUnit2などでもそのような状態になっています。例えば
PHPUnit2/Framework/TestCase.phpの中にあるクラスは TestCaseクラスではなく
PHPUnit2_Framework_TestCaseクラスです。

長文お許しください。
もうすでに議論されている話題でしたら申し訳ありません。無視してください。
何かお手伝いできることがあれば、がんばりますのでよろしくお願いします。
失礼いたします。


seasar-php メーリングリストの案内