Paradigm Shift Design

ISHITOYA Kentaro's blog.

S2Dao.php5ではまる.

いやー2時間ぐらいはまった.
エラーメッセージとスタックは

exception 'S2Container_IllegalArgumentException' with message 'Illegal argument args[0] must be <ReflectionMethod>' in C:\cygwin\home\kent\www\modellista\lib\s2container.php5\build\s2container.php5\s2container.core.classes.php:2923
Stack trace:
#0 C:\cygwin\home\kent\www\modellista\lib\s2container.php5\build\s2container.php5\s2container.core.classes.php(2518): S2Container_MethodUtil::invoke(NULL, Object(Modellista_AutoNewsEntity), NULL)
#1 C:\cygwin\home\kent\www\modellista\lib\s2dao.php5\build\s2dao.php5\s2dao.core.classes.php(725): S2Container_PropertyDescImpl->getValue(Object(Modellista_AutoNewsEntity))
#2 C:\cygwin\home\kent\www\modellista\lib\s2dao.php5\build\s2dao.php5\s2dao.core.classes.php(678): S2Dao_AbstractAutoHandler->preUpdatePropertyTypes(Object(Modellista_AutoNewsEntity))
#3 C:\cygwin\home\kent\www\modellista\lib\s2dao.php5\build\s2dao.php5\s2dao.core.classes.php(846): S2Dao_AbstractAutoHandler->execute(Array)
#4 C:\cygwin\home\kent\www\modellista\lib\s2dao.php5\build\s2dao.php5\S2Dao\S2Dao_PagerS2DaoInterceptorWrapper.class.php(82): S2Dao_AbstractAutoStaticCommand->execute(Array)
#5 C:\cygwin\home\kent\www\modellista\lib\s2dao.php5\build\s2dao.php5\S2Dao\S2Dao_PagerS2DaoInterceptorWrapper.class.php(54): S2Dao_PagerS2DaoInterceptorWrapper->invokePagerWithLimitOffsetQuery(Object(S2Container_S2MethodInvocationImpl))
#6 C:\cygwin\home\kent\www\modellista\lib\s2container.php5\build\s2container.php5\s2container.core.classes.php(3058): S2Dao_PagerS2DaoInterceptorWrapper->invoke(Object(S2Container_S2MethodInvocationImpl))
#7 C:\cygwin\home\kent\www\modellista\lib\s2container.php5\build\s2container.php5\S2Container\S2Container_AopConcreteClassGenerator.class.php(77) : eval()'d code(301): S2Container_S2MethodInvocationImpl->proceed()
#8 C:\cygwin\home\kent\www\modellista\lib\s2container.php5\build\s2container.php5\S2Container\S2Container_AopConcreteClassGenerator.class.php(77) : eval()'d code(271): Modellista_AutoNewsDao_EnhancedByS2AOP->__invokeMethodInvocationProceed_EnhancedByS2AOP(Object(Modellista_AutoNewsEntity), 'insert')
#9 C:\cygwin\home\kent\www\modellista\lib\ficus\db\s2dao\models\S2DaoEntity.php(226): Modellista_AutoNewsDao_EnhancedByS2AOP->insert(Object(Modellista_AutoNewsEntity))
#10 C:\cygwin\home\kent\www\modellista\data\pages\NewsManagerPage.php(22): Ficus_S2DaoEntity->insert()
#11 [internal function]: Modellista_NewsManagerPage->doUpload(Object(Ficus_PageRequest))
#12 C:\cygwin\home\kent\www\modellista\lib\ficus\pages\Page.php(108): call_user_func(Array, Object(Ficus_PageRequest))
#13 [internal function]: Ficus_Page->__call('upload', Array)
#14 [internal function]: Modellista_NewsManagerPage->upload(Object(Ficus_PageRequest))
#15 C:\cygwin\home\kent\www\modellista\lib\ficus\pages\PageController.php(144): call_user_func(Array, Object(Ficus_PageRequest))
#16 C:\cygwin\home\kent\www\modellista\htdocs\index.php(46): Ficus_PageController->execute()
#17 {main}

って感じ.で,ソースを見ると,
s2container.core.classes.php:2518行目は

public final function getValue($target)
{
    return S2Container_MethodUtil::invoke($this->readMethod_,$target, null);
}

という箇所.うーん?getterがない?どういうことだ.
呼び出している側のs2dao.core.classes.phpは

   protected function preUpdatePropertyTypes($bean){
        $bmd = $this->getBeanMetaData();
        $c = $bmd->getPropertyTypeSize();
        for($i = 0; $i < $c; $i++){
            $pt = $bmd->getPropertyType($i);
            $pd = $pt->getPropertyDesc();
            $value = $pd->getValue($bean);
            $pt->setValueType(gettype($value));
        }
    }

となっている.あぁ,値を取得しようとして落ちている.
でも,getter/setterはすべてあるのになぜ?とおもって,

var_dump($pd->getPropertyName());
$value = $pd->getValue($bean);

としてみると,

string(2) "id"
string(13) "controlTypeId"
string(5) "title"
string(4) "text"
string(3) "url"
string(6) "image1"
string(6) "image2"
string(4) "date"
string(5) "blank"
string(10) "entityName"
string(9) "timeStamp"


とか表示されて,エラーが出る.
timeStampなんてプロパティーは定義していない…あっ!


Ficusでは,S2Daoエンティティを自動生成していて,
Ficus_Bean->Ficus_S2DaoEntity->App_AutoNewsEntity
と継承している.
で,動かなくなる前に, created_on より created_at を使う。 - こせきの技術日記を参考に,RoRのActiveRecordsをまねて,タイムスタンプを突っ込むようにしたのでした.
…そのメソッド名が,setTimeStamp.


setterがあったらAOPの対象になっちゃうのね…
getter/setterがあるかどうか確かめてから,インジェクションするか決めてほしいなと思いました.そうでなければ,S2Container_ReaderMethodNotFoundRuntimeExceptionとか飛ばしてほしいと思ったり.


最近は更新も止まっているみたいだし,AOPはやっぱりPHPにはそぐわない開発手法だったのかなぁ.うーん.
と思ったら,The Seasar Project - S2Container.PHPで1.2.0がリリースされてた.
ちゃんとおっかけないとな.