本人较菜,请问各位侠士,如何在PHP中达到EventStack的NotifyWatcher方法可以将取得的数据返还给welcome.php指定的回调函数,我哪里写的不对啊 ???出现的错误为:Fatal error: Function name must be a string in /home/latel/Workspace/new_zhebo/module/EventStack.php on line ××/app/welcome.php<?php
 
if (!defined("__IS_ROOT")) die("Access Denied");
 
global $EventStack;
 
//闭包函数(回调)
$fGetSettings = function($oSettingDaemon) {
    //处理回调返回的系统设置数据模型
    echo $oSettingDaemon;
};
 
//请求数据原型
$EventStack->addEvent(
    "DATA_REQUEST",
    serialize(array(
        array(
            "request" => "settingDaemon"
        )
    )),
    $fGetSettings,
    null
);
?>/EventStack.php
<?php
//事件堆栈处理组件
/*数
 */
//已知的事件戳记
/*
 */
 
if (!defined("__IS_ROOT")) die("Access Denied");
 
class EventStack extends Init{
    private $_aWatcherRegistry = array();//已注册的观察者列表
    private $_aEventStack = array();//事件堆栈
    private $_aCallbackRegistry = array();//已注册的回调函数
 
    function __construct() {
    }
    function __destruct() {
        //将关键信息存储至数据源的Log表
        //根据调试开关,决定是否输出调试信息至页面
    }
    function __toString() {
    }
    ##A##
    public function addEvent($sStamp = "ISSUE_TRACK", $sValue, $fHandler = null, $mScope = null) {
        /*sStamp: 此条消息的戳记
         *sValue: 序列化的数组
         * fHandler(function): 匿名回调函数
         * mScope(mixed type): 回调函数的上下文环境,
             * null表示传入的handler函数是一个全局函数,
             * 字符串类型表示传入的handler函数是scope类的静态函数,
             * 对象类型表示传入的scope是一个对象,handler函数是对象的一个方法
         */
        $this->_aEventStack[] = array(
            "stamp" => $sStamp,
            "value" => $sValue,
            "handler" => $fHandler,
            "scope" => $mScope,
            "timestamp" => time()
        );
        $iKey =  sizeof($this->_aEventStack) - 1;
        $this->notifyWatcher($iKey);
        return $iKey;
    }
    public function addWatcher($oWatcher, $sWatchStamp) {
    }
    ##C##
    public function clearEventStack() {
        //清空事件堆栈
    }
    ##E##
    public function exportEventStack() {
        //输出调试信息
    }
    ##G##
    public function getStack($iStackId) {
        //根据是否提供堆栈序号,返回堆栈列表或指定堆栈的内容
    }
    ##N##
    private function notifyWatcher($iKey) {
        //推送事件至相应的观察者
        if (array_key_exists($this->_aEventStack[$iKey]["stamp"], $this->_aWatcherRegistry)) {
            $mCallback = $this->_aWatcherRegistry[$this->_aEventStack[$iKey]["stamp"]](
                $this->_aEventStack[$iKey]["stamp"],
                $this->_aEventStack[$iKey]["value"],
                $this->_aEventStack[$iKey]["handler"],
                $this->_aEventStack[$iKey]["scope"]
            );
            //如果指定了回调函数,依据观察者返回的数据,做出具体的操作
            if (isset($this->_aEventStack[$iKey]["fHandler"]) && !$mCallback) {
                $func = $this->_aEventStack[$iKey]["fHandler"];
                $func($mCallback);
            } else {
                $func(null);
            }
        }
    }
    ##R##
    public function removeWatcher($sWatchStamp) {
        //移除指定的观察者
    }
}
 
 
?>

解决方案 »

  1.   

    还是那样,连错误信息都不给全!$fGetSettings = function($oSettingDaemon) {
        //处理回调返回的系统设置数据模型
        echo $oSettingDaemon;
    };$EventStack = new EventStack;//请求数据原型
    $EventStack->addEvent(
        "DATA_REQUEST",
        serialize(array(
            array(
                "request" => "settingDaemon"
            )
        )),
        $fGetSettings,
        null
    );class EventStack {
        private $_aWatcherRegistry = array();//已注册的观察者列表
        private $_aEventStack = array();//事件堆栈
        private $_aCallbackRegistry = array();//已注册的回调函数
      
        function __construct() {
        }
        function __destruct() {
            //将关键信息存储至数据源的Log表
            //根据调试开关,决定是否输出调试信息至页面
        }
        function __toString() {
        }
        ##A##
        public function addEvent($sStamp = "ISSUE_TRACK", $sValue, $fHandler = null, $mScope = null) {
    print_r(func_get_args());//传入正确
            /*sStamp: 此条消息的戳记
             *sValue: 序列化的数组
             * fHandler(function): 匿名回调函数
             * mScope(mixed type): 回调函数的上下文环境,
                 * null表示传入的handler函数是一个全局函数,
                 * 字符串类型表示传入的handler函数是scope类的静态函数,
                 * 对象类型表示传入的scope是一个对象,handler函数是对象的一个方法
             */
            $this->_aEventStack[] = array(
                "stamp" => $sStamp,
                "value" => $sValue,
                "handler" => $fHandler,
                "scope" => $mScope,
                "timestamp" => time()
            );
    print_r($this->_aEventStack);//赋值正确
            $iKey =  sizeof($this->_aEventStack) - 1;
            $this->notifyWatcher($iKey);
            return $iKey;
        }
        public function addWatcher($oWatcher, $sWatchStamp) {
        }
        ##C##
        public function clearEventStack() {
            //清空事件堆栈
        }
        ##E##
        public function exportEventStack() {
            //输出调试信息
        }
        ##G##
        public function getStack($iStackId) {
            //根据是否提供堆栈序号,返回堆栈列表或指定堆栈的内容
        }
        ##N##
        private function notifyWatcher($iKey) {
            //推送事件至相应的观察者
            if (array_key_exists($this->_aEventStack[$iKey]["stamp"], $this->_aWatcherRegistry)) {
                $mCallback = $this->_aWatcherRegistry[$this->_aEventStack[$iKey]["stamp"]](
                    $this->_aEventStack[$iKey]["stamp"],
                    $this->_aEventStack[$iKey]["value"],
                    $this->_aEventStack[$iKey]["handler"],
                    $this->_aEventStack[$iKey]["scope"]
                );
                //如果指定了回调函数,依据观察者返回的数据,做出具体的操作
                if (isset($this->_aEventStack[$iKey]["fHandler"]) && !$mCallback) {
                    $func = $this->_aEventStack[$iKey]["fHandler"];
                    $func($mCallback);
                } else {
                    $func(null);
                }
            }
        }
        ##R##
        public function removeWatcher($sWatchStamp) {
            //移除指定的观察者
        }
    }Array
    (
        [0] => DATA_REQUEST
        [1] => a:1:{i:0;a:1:{s:7:"request";s:13:"settingDaemon";}}
        [2] => Closure Object
            (
                [parameter] => Array
                    (
                        [$oSettingDaemon] => <required>
                    )        )    [3] => 
    )
    Array
    (
        [0] => Array
            (
                [stamp] => DATA_REQUEST
                [value] => a:1:{i:0;a:1:{s:7:"request";s:13:"settingDaemon";}}
                [handler] => Closure Object
                    (
                        [parameter] => Array
                            (
                                [$oSettingDaemon] => <required>
                            )                )            [scope] => 
                [timestamp] => 1383634959
            ))
      

  2.   

    板大。您好,我把所有代码都贴出来,您就帮我解决下吧。文件:app/welcome.php<?php//边界判定
    if (!defined("__IS_ROOT")) die("Access Denied");
    if (!defined("__IS_APP_ENABLE")) die("Access Denied");global $EventStack, $Smarty;$oSettingDaemon = null;
    $oArchiveList_Case = null;//闭包函数(回调)
    $fGetSettings = function() use (&$oSettingDaemon) {
    //处理回调返回的系统设置数据模型
    echo "wow";
    };$fDataMap = function() use (&$oArchiveList_Case) {
    //处理回调返回的数据模型中的数据地图
    //模板赋值
    echo "dota";
    };//请求数据原型
    $EventStack->addEvent(//添加数据请求至事件堆栈
    "DATA_REQUEST",
    serialize(array(
    array(
    "request" => "settingDaemon"
    )
    )),
    $fGetSettings,
    null
    );$EventStack->addEvent(//添加数据请求至事件堆栈
    "DATA_REQUEST",
    serialize(array(
    array(
    "request" => "archiveList",
    "index" => "case",
    "sort" => "date DESC",
    "limit" => "0, 8"
    ),
    array(
    "request" => "archiveList",
    "index" => "case",
    "sort" => "successful_flag DESC",
    "limit" => "0, 8"
    ),
    array(
    "request" => "archiveList",
    "index" => "detection",
    "sort" => "hot_flag DESC",
    "limit" => "0, 5"
    ),
    array(
    "request" => "archiveList",
    "index" => "news",
    "sort" => "date DESC",
    "limit" => "0, 2"
    ),
    array(
    "request" => "archiveList",
    "index" => "news_industrial",
    "sort" => "hot_flag DESC",
    "limit" => "0, 1"
    ),
    array(
    "request" => "userList",
    "level" => "worker"
    ),
    array(
    "request" => "archiveList",
    "index" => "news",
    "sort" => "count_clicks DESC",
    "limit" => "0, 3"
    )
    )),
    $fDataMap,//指定回调函数
    null//指明上下文环境
    );//为模版绑定数据//输出页面
    $Smarty->display("kit-full.tpl");?>文件: EventStack.php<?php
    //事件堆栈处理组件
    /*
     * 堆栈程序应当只负责本职工作,即如实的记录和管理事件堆栈
     * 堆栈程序对外界应当仅提供 添加观察者,移除观察者,添加事件,清空事件,获取堆栈列表或内容的接口
     * 堆栈程序不应当负责对外的逻辑处理
     * 通过两种方式主动向外界通讯
     * 观察者:当有观察者(通常是个对象)指定的事件发生时,主动调用该组件的__invoke函数
     * 回调函数,当添加事件时,事件的添加者可指定一个回调函数,当观察者对此事件做出处理之后,将会激活此回调函数
     */
    //已知的事件戳记
    /*
     * NOTICE, 系统运行时的提示消息
     * WARNING, 系统运行时的警告级消息
     * ERROR, 系统运行时的错误级消息
     * ISSUE_TRACK, 由错误处理和安全组件注册的戳记
     * DATA_REQUEST, 由数据模型组件注册的戳记
     */if (!defined("__IS_ROOT")) die("Access Denied");class EventStack extends Init{
    private $_aWatcherRegistry = array();//已注册的观察者列表
    private $_aEventStack = array();//事件堆栈
    private $_aCallbackRegistry = array();//已注册的回调函数 function __construct() {
    $this->addEvent(
    "NOTICE",
    serialize(array("Module(Core) and Module(Pdo) is initiated"))
    );
    $this->addEvent(
    "NOTICE",
    serialize(array("Module(EventStack) is initiated"))
    );
    }
    function __destruct() {
    //将关键信息存储至数据源的Log表
    //根据调试开关,决定是否输出调试信息至页面
    $bDebugLock = parent::getArgument("lockring", "debug");
    if ($bDebugLock) {
    $this->exportEventStack();
    }
    }
    function __toString() {
    }
    ##A##
    public function addEvent($sStamp = "ISSUE_TRACK", $sValue, $fHandler = null, $mScope = null) {
    /*sStamp: 此条消息的戳记
     *sValue: 序列化的数组
     * fHandler(function): 匿名回调函数
     * mScope(mixed type): 回调函数的上下文环境,
     * null表示传入的handler函数是一个全局函数,
     * 字符串类型表示传入的handler函数是scope类的静态函数,
     * 对象类型表示传入的scope是一个对象,handler函数是对象的一个方法
     */
    $this->_aEventStack[] = array(
    "stamp" => $sStamp,
    "value" => $sValue,
    "handler" => $fHandler,
    "scope" => $mScope,
    "timestamp" => time()
    );
    $iKey =  sizeof($this->_aEventStack) - 1;
    $this->toast($iKey);
    return $iKey;
    }
    public function addWatcher($oWatcher, $sWatchStamp) {
    //添加观察者
    if(is_object($oWatcher)) {
    $this->_aWatcherRegistry[$sWatchStamp] = $oWatcher;
    $this->addEvent(
    "NOTICE",
    serialize(array("Watcher($sWatchStamp) is added on EventStack"))
    );
    }
    }
    ##C##
    public function clearEventStack() {
    //清空事件堆栈
    unset($this->_aEventStack);
    $this->addEvent(
    "NOTICE",
    serialize(array("EventStack is cleared"))
    );
    }
    ##E##
    public function exportEventStack() {
    //输出调试信息
    echo "debug";
    echo "_________________________________________________><br/>";
    foreach ($this->_aEventStack as $key => $value) {
    //if (in_array($value["stamp"], array("NOTICE", "WARNING", "ERROR", "ISSUE_TRACK"))) {
    echo "<b>Stackid:</b> $key <b>Stamp</b> ".$value["stamp"]." <b>Backtrace</b> ".$value["value"]." <b>TIMESTAMP</b> ".date("h:m:s",$value["timestamp"])."<br/>";
    //}
    }
    }
    ##G##
    public function getStack($iStackId) {
    //根据是否提供堆栈序号,返回堆栈列表或指定堆栈的内容
    if ($iStackId) {
    if(!isset($_aEventStack[$iStackId])) {
    $this->addEvent(
    "ISSUE_TRACK",
    serialize(array(
    "sLevel" => "notice",
    "sLocate" => "",
    "sMessage" => "Requested stack id($iStackId) doesn't existed in EventStack",
    "isLog" => true,
    "bDirectOutput" => false
    ))
    );
    return null;
    } else {
    return $_aEventStack[$iStackId];
    }
    } else {
    return $this->_aEventStack;
    }
    }
    ##L##
    public function loopEvent() {
    //遍历事件堆栈
    //在所有其他组件运行完成时执行
    #如果发现需要回调的或被观察者绑定的事件,则作出具体动作
    foreach ($this->_aEventStack as $aEvent) {
    //推送相应事件至绑定此类型事件的观察者
    if (array_key_exists($aEvent["stamp"], $this->_aWatcherRegistry)) {
    $mCallback = $this->_aWatcherRegistry[$aEvent["stamp"]] (
    $aEvent["stamp"],
    $aEvent["value"]
    );
    }
    //检查回调函数
    $fFunc = $aEvent["fHandler"];
    if (isset($mCallback) && is_callable($fFunc)) {
    $fFunc($mCallback);
    } else {
    }
    }
    }
    ##N##
    private function toast($iKey) {
    //推送事件至相应的观察者
    if (array_key_exists($this->_aEventStack[$iKey]["stamp"], $this->_aWatcherRegistry)) {
    $mCallback = $this->_aWatcherRegistry[$this->_aEventStack[$iKey]["stamp"]](
    $this->_aEventStack[$iKey]["stamp"],
    $this->_aEventStack[$iKey]["value"]
    );
    //如果指定了回调函数,依据观察者返回的数据,做出具体的操作
    if (isset($this->_aEventStack[$iKey]["fHandler"]) && !$mCallback) {
    echo $func = $this->_aEventStack[$iKey]["fHandler"];
    echo 1;
    $func($mCallback);
    } else {
    echo 2;
    $func(null);
    }
    }
    }
    ##R##
    public function removeWatcher($sWatchStamp) {
    //移除指定的观察者
    unset($this->_aWatcherRegistry[$sWatchStamp]);
    if (empty($this->_aWatcherRegistry[$sWatchStamp])) {
    $this->addEvent(
    "NOTICE",
    serialize(array("Watcher($sWatchStamp) is removed"))
    );
    return true;
    } else {
    return false;
    }
    }
    }
    ?>
    出错信息:Fatal error: Function name must be a string in C:\wamp\www\newzhebo\module\EventStack.php on line 157Call Stack
    # Time Memory Function Location
    1 0.0000 146864 {main}( ) ..\index.php:0
    2 0.0540 1074504 Init->start( ) ..\index.php:57
    3 0.0540 1074520 App->__invoke( ) ..\Init.php:152
    4 0.0550 1083208 require_once( 'C:\wamp\www\newzhebo\module\app\welcome.php' ) ..\App.php:30
    5 0.0550 1084664 EventStack->addEvent( ) ..\welcome.php:34
    6 0.0550 1085176 EventStack->toast( ) ..\EventStack.php:65
      

  3.   


    文件:Model.php<?php
    //数据模型组件if (!defined("__IS_ROOT")) die("Access Denied");interface iModeldo{
    function __toString();//将数据模型的数据转化为字符串返回以方便传递
    function onModel($sModel, $aArgPack);//生成数据模型
    function onModify($sModel, $aSqlPack);//修改数据模型
    }class SettingDaemon{
    //[系统运行时设置]数据模型
    #variables
    public $aSettingDaemon; #functions
    function __toString() {
    $aObjectArray = array(
    "asettingdaemon" => $this->aSettingDaemon
    );
    print_r($aObjectArray);
    } function onModel($sModel, $aArgPack) {
    if ($sModel != "settingdaemon") return false;
    global $Core, $EventStack, $Pdo;
    try {
    $aDataBaseSoftLink = $Core->getArgument("db", "softLink");
    $sTable = $aDataBaseSoftLink["system"];
    $sSql = "SELECT * FROM $sTable";
    $aResult = $Pdo->query($sSql);
    $sSettingDaemon = $aResult->fetchColumn();
    $this->aSettingDaemon = unserialize($sSettingDaemon);
    //返回数据模型
    return $this;
    } catch(PDOException $e) {
    $EventStack->addEvent(
    "ISSUE_TRACK",
    serialize(array(
    "sLevel" => "ERROR",
    "sLocate" => "Model->on->SettingDaemon",
    "sMessage" => "Requested Model(SettingDaemon) failed, possibly reason:".$e->getMessage(),
    "isLog" => true,
    "bDirectOutput" => false
    ))
    );
    return false;
    }
    }
    function onModify($sModel, $aSqlPack) {
    if ($sModel != "settingdaemon") return false;
    global $EventStack, $Pdo;
    try {
    $aDataBaseSoftLink = $Core->getArgument("db", "softlink");
    $sTable = $aDataBaseSoftLink["system"];
    foreach ($aSqlPack as $sSql) {
    $Pdo->query($sSql);
    }
    } catch(PDOException $e) {
    $EventStack->addEvent(
    "ISSUE_TRACK",
    serialize(array(
    "sLevel" => "ERROR",
    "sLocate" => "Model->modify->SettingDaemon",
    "sMessage" => "",
    "isLog" => true,
    "bDirectOutput" => false
    ))
    );
    }
    }
    }class StaticWords{
    //[静态文本]数据模型
    #variables
    public $sWelcomeIntro;
    public $sAboutZhebo;
    public $sAboutCulture;
    public $sAboutLaboratory;
    public $sAboutTeam;
    public $sAboutHornor;
    public $sFootIntro; #functions
    function __toString() {
    }
    function onModel($sModel, $aArgPack) {
    if ($sModel != "staticwords") return false;
    global $Core, $EventStack, $Pdo;
    try {
    $aDataBaseSoftLink = $Core->getArgument("db", "softLink");
    $sTable = $aDataBaseSoftLink["system"];
    $sSql = "SELECT * FROM $sTable";
    $aResult = $Pdo->query($sSql);
    $aResultLine = $aResult->fetch();
    $this->sWelcomeIntro = $aResultLine("introduction_short");
    $this->sAboutZhebo = $aResultLine("introduction_all");
    $this->sAboutCulture = $aResultLine("introduction_culture");
    $this->sAboutLaboratory = $aResultLine("introduction_lab");
    $this->sAboutTeam = $aResultLine("introduction_team");
    $this->sAboutHornor = $aResultLine("introduction_hornor");
    $this->sFootIntro = $aResultLine("introduction_foot");
    //返回数据模型
    return $this;
    } catch(PDOException $e) {
    $EventStack->addEvent(
    "ISSUE_TRACK",
    serialize(array(
    "sLevel" => "ERROR",
    "sLocate" => "Model->on->SettingDaemon",
    "sMessage" => "Requested Model(SettingDaemon) failed, possibly reason:".$e->getMessage(),
    "isLog" => true,
    "bDirectOutput" => false
    ))
    );
    return false;
    }
    }
    function onModify($sModel, $aSqlPack) {
    if ($sModel != "staticwords") return false;
    global $EventStack, $Pdo;
    try {
    //取得所需表名
    $aDataBaseSoftLink = $Core->getArgument("db", "softlink");
    $sTable = $aDataBaseSoftLink["system"];
    //验证参数
    //生成Sql查询语句
    //更新数据
    //返回对象
    return $this;
    } catch(PDOException $e) {
    $EventStack->addEvent(
    "ISSUE_TRACK",
    serialize(array(
    "sLevel" => "ERROR",
    "sLocate" => "Model->modify->SettingDaemon",
    "sMessage" => "",
    "isLog" => true,
    "bDirectOutput" => false
    ))
    );
    }
    }
    }class ArchiveContent implements iModeldo{
    //[文章内容]数据模型
    #variables
    public $iId;
    public $sIndex;
    public $iAuthor;
    public $sAuthorName;
    public $sTimestamp;
    public $sTitle;
    public $sContent;
    public $bHotFlag;
    public $iCountClicks; #functions
    function __toString() {
    }
    function onModel($sModel, $aArgPack) {
    if ($sModel != "archivecontent") return false;
    global $Core, $EventStack;
    extract($aArgPack);
    try {
    //获得所需的数据表名
    $aDataBaseSoftLink = $Core->getArgument("db", "softLink");
    $sTable = $aDataBaseSoftLink["archive"];
    //核实参数
    $sSqlId = isset($iId)? " WHERE `id`=$iId": " WHERE `id`=1";
    //生成查询Sql
    $sSql = "SELECT * FROM $sTable".$sSqlId;
    //取得数据
    $aResult = $Pdo->query($sSql);
    while ($aRow = $aResult->fetch()) {
    $this->aArchiveList[] = array(
    "id" => $aRow["id"],
    "index" => $aRow["index"],
    "date" => $aRow["date"],
    "author" => $aRow["author"],
    "title" => $aRow["title"],
    "content" => $aRow["content"],
    "hot_flag" => $aRow["hot_flag"],
    "successful_flag" => $aRow["successful_flag"],
    "count_clicks" => $aRow["count_clicks"]
    );
    }
    //返回数据模型
    return $this;
    } catch(PDOException $e) {
    $EventStack->addEvent(
    "ERROR",
    serialize(array(
    "sLevel" => "ERROR",
    "sLocate" => "Model->on->ArchiveContent",
    "sMessage" => "Requested Model(ArchiveContent) failed, possibly reason:".$e->getMessage(),
    "isLog" => true,
    "bDirectOutput" => false
    ))
    );
    }
    }
    function onModify($sModel, $aSqlPack) {
    if ($sModel != "archivecontent") return false;
    }
    }class Model extends Init{
    #variables
    private $_aModelMap = array();//戳记和类名的实际对应
    private $_aModels = array();//已注册的数据模型模块 #functions
    function __construct() {
    $this->registry();
    //添加所有的数据模块至数据模块列表
    $this->registerModel("SettingDaemon");
    $this->registerModel("StaticWords");
    $this->registerModel("ArchiveContent");
    $this->registerModel("ArchiveList");
    $this->registerModel("UserDetail");
    $this->registerModel("UserList");
    $this->registerModel("FriendLinkList");
    $this->registerModel("ChattingLine");
    $this->registerModel("SearchResult");
    }
    function __invoke($sStamp, $sValue) {
    //收到事件堆栈推送的消息
    if ($sStamp != "DATA_REQUEST") {
    //复查消息戳记
    die("Module(Model) recived wrong toast from EventStack");
    } else {
    $aValue = unserialize($sValue);
    //核查参数
    if (!is_array($aValue)) {
    //数据请求者传递給本组件的参数不合法
    } else {
    foreach ($aValue as $aArgPack) {
    //获得数据模型名
    $sModelName = strtolower($aArgPack["request"]);
    //提取传递给数据模型的参数列表
    array_shift($aArgPack);
    //生成需要的数据模型对象
    $oModel = $this->creatModel($sModelName);
    //添加次数据模型对象至保存的列表
    $this->_aModels[] = $oModel;
    //继续该数据模型填充数据,并保存至要返回的数据模型列表中
    $oModel->onModel($sModelName, $aArgPack);
    }
    //将所有数据模型对象作为参数返回至事件堆栈, 事件堆栈会视回调函数返回至数据请求方,注意是一个数组
    return $this->_aModels;
    }
    }
    } ##R##
    function registry() {
    //注册此组件为事件堆栈组件的观察者
    global $EventStack;
    $EventStack->addWatcher($this, "DATA_REQUEST");
    $EventStack->addWatcher($this, "DATA_MODIFY");
    } private function registerModel($sModelName) {
    //注册戳记和类名的对应关系
    $this->_aModelMap[strtolower($sModelName)] = $sModelName;
    } private function creatModel($sModelName) {
    //以工厂模式生成数据模型
    if (in_array($sModelName, array_keys($this->_aModelMap))) {
    $sClassName = $this->_aModelMap[$sModelName];
    return new $sClassName();
    } else {
    return null;
    }
    }}?>
      

  4.   

    文件:App.php<?php
    //应用程序组件
    /*
     * 和前端挂钩的组件
     * 从Router组件获得基本的请求信息后
     * 1.加载框架,获得框架的数据原型并绑定
     * 2.加载具体的页面组件,该页面组件将自行请求数据源型并绑定
     * 3.显示合成并处理后的页面
     */if(!defined("__IS_ROOT")) die("Access Denied");class App extends Init{
    #variables
    private $_sApp;//指定具体的应用组件 #functions
    function __construct() {
    define("__IS_APP_ENABLE", true);
    }
    function __invoke() {
    //通过使用$App()即可完成页面显示
    global $Router;
    $aAppAvailableList = parent::getArgument("app");
    $sApp = $Router->getController();
    if (in_array($sApp, $aAppAvailableList)) {
    $this->_sApp = $sApp;
    $sFilePath = "module/app/".$sApp.".php";
    if (is_file($sFilePath) && is_readable($sFilePath)) {
    require_once($sFilePath);
    }
    }
    }
    }?>
      

  5.   

    你给全错误信息不经行了吗?
    Fatal error: Function name must be a string in C:\wamp\www\newzhebo\module\EventStack.php on line 157
    不就是 EventStack.php 的 157 行出错吗?
     EventStack.php
    143    private function toast($iKey) {
    144        //推送事件至相应的观察者
    145        if (array_key_exists($this->_aEventStack[$iKey]["stamp"], $this->_aWatcherRegistry)) {
    146            $mCallback = $this->_aWatcherRegistry[$this->_aEventStack[$iKey]["stamp"]](
    147                $this->_aEventStack[$iKey]["stamp"],
    148                $this->_aEventStack[$iKey]["value"]
    149            );
    150            //如果指定了回调函数,依据观察者返回的数据,做出具体的操作
    151            if (isset($this->_aEventStack[$iKey]["fHandler"]) && !$mCallback) {
    152                echo $func = $this->_aEventStack[$iKey]["fHandler"];
    153                echo 1;
    154                $func($mCallback);
    155            } else {
    156                echo 2;
    157                $func(null); //这个 $func 在哪里赋值的?
                }
            }
        }
    154 的是在 152 赋值的,哪 157 的 $func 在哪里赋值的?
     
    至少要把 $func = $this->_aEventStack[$iKey]["fHandler"]; 放到条件分支外面吧?
      

  6.   

    我把代码改成这样,还是上面的错误。private function toast($iKey) {
    //推送事件至相应的观察者
    if (array_key_exists($this->_aEventStack[$iKey]["stamp"], $this->_aWatcherRegistry)) {
    $mCallback = $this->_aWatcherRegistry[$this->_aEventStack[$iKey]["stamp"]](
    $this->_aEventStack[$iKey]["stamp"],
    $this->_aEventStack[$iKey]["value"]
    );
    //如果指定了回调函数,依据观察者返回的数据,做出具体的操作
    $func = $this->_aEventStack[$iKey]["fHandler"];
    if (isset($this->_aEventStack[$iKey]["fHandler"]) && !$mCallback) {
    echo 1;
    $func($mCallback);
    } else {
    echo 2;
    $func(null);
    }
    }
    }
      

  7.   

    var_dump EventStack对象实例的结果如下object(EventStack)[5]
      private '_aWatcherRegistry' => 
        array (size=3)
          'ISSUE_TRACK' => 
            object(Issue)[6]
              private '_aLastIssue' => 
                array (size=0)
                  ...
          'DATA_REQUEST' => 
            object(Model)[8]
              private '_aModelMap' => 
                array (size=9)
                  ...
              private '_aModels' => 
                array (size=8)
                  ...
              protected 'aInitArguments' => 
                array (size=6)
                  ...
              protected 'aModules' => 
                array (size=0)
                  ...
              private '_aModuleList' (Init) => 
                array (size=11)
                  ...
          'DATA_MODIFY' => 
            object(Model)[8]
              private '_aModelMap' => 
                array (size=9)
                  ...
              private '_aModels' => 
                array (size=8)
                  ...
              protected 'aInitArguments' => 
                array (size=6)
                  ...
              protected 'aModules' => 
                array (size=0)
                  ...
              private '_aModuleList' (Init) => 
                array (size=11)
                  ...
      private '_aEventStack' => 
        array (size=17)
          0 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:41:"Module(Core) and Module(Pdo) is initiated";}' (length=59)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          1 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:31:"Module(EventStack) is initiated";}' (length=49)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          2 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:43:"Watcher(ISSUE_TRACK) is added on EventStack";}' (length=61)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          3 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:26:"Module(Issue) is initiated";}' (length=44)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          4 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:29:"Module(HashUtls) is initiated";}' (length=47)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          5 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:44:"Watcher(DATA_REQUEST) is added on EventStack";}' (length=62)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          6 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:43:"Watcher(DATA_MODIFY) is added on EventStack";}' (length=61)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          7 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:26:"Module(Model) is initiated";}' (length=44)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          8 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:23:"Module(IM) is initiated";}' (length=41)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          9 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:27:"Module(Router) is initiated";}' (length=45)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          10 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:30:"Module(Operation) is initiated";}' (length=48)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          11 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:24:"Module(App) is initiated";}' (length=42)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          12 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:25:"Module(User) is initiated";}' (length=43)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          13 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:29:"Module(ApiChain) is initiated";}' (length=47)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          14 => 
            array (size=5)
              'stamp' => string 'NOTICE' (length=6)
              'value' => string 'a:1:{i:0;s:30:"Module(SmartyMod) is initiated";}' (length=48)
              'handler' => null
              'scope' => null
              'timestamp' => int 1383656323
          15 => 
            array (size=5)
              'stamp' => string 'DATA_REQUEST' (length=12)
              'value' => string 'a:1:{i:0;a:1:{s:7:"request";s:13:"settingDaemon";}}' (length=51)
              'handler' => 
                object(Closure)[21]
                  ...
              'scope' => null
              'timestamp' => int 1383656323
          16 => 
            array (size=5)
              'stamp' => string 'DATA_REQUEST' (length=12)
              'value' => string 'a:7:{i:0;a:4:{s:7:"request";s:11:"archiveList";s:5:"index";s:4:"case";s:4:"sort";s:9:"date DESC";s:5:"limit";s:4:"0, 8";}i:1;a:4:{s:7:"request";s:11:"archiveList";s:5:"index";s:4:"case";s:4:"sort";s:20:"successful_flag DESC";s:5:"limit";s:4:"0, 8";}i:2;a:4:{s:7:"request";s:11:"archiveList";s:5:"index";s:9:"detection";s:4:"sort";s:13:"hot_flag DESC";s:5:"limit";s:4:"0, 5";}i:3;a:4:{s:7:"request";s:11:"archiveList";s:5:"index";s:4:"news";s:4:"sort";s:9:"date DESC";s:5:"limit";s:4:"0, 2";}i:4;a:4:{s:7:"request'... (length=814)
              'handler' => 
                object(Closure)[22]
                  ...
              'scope' => null
              'timestamp' => int 1383656323
      private '_aCallbackRegistry' => 
        array (size=0)
          empty
      protected 'aInitArguments' => 
        array (size=6)
          'app' => 
            array (size=3)
              0 => string 'about' (length=5)
              1 => string 'archive' (length=7)
              2 => string 'welcome' (length=7)
          'db' => 
            array (size=2)
              'connect' => 
                array (size=3)
                  ...
              'softLink' => 
                array (size=9)
                  ...
          'lockring' => 
            array (size=2)
              'debug' => boolean true
              'dataUpdate' => boolean true
          'root' => 
            array (size=2)
              'excute' => string '/home/latel/Workspace/zhebo' (length=27)
              'website' => string 'http://www.zhebotest.com/' (length=25)
          'smarty' => 
            array (size=9)
              'template_dir' => string 'assets/html/templates' (length=21)
              'compile_dir' => string 'assets/html/templates_c' (length=23)
              'config_dir' => string 'assets/html/configs' (length=19)
              'cache_dir' => string 'assets/html/cache' (length=17)
              'cache_lifetime' => int 86400
              'caching' => boolean true
              'left_delimiter' => string '{#' (length=2)
              'right_delimiter' => string '#}' (length=2)
              'debugging' => boolean false
          'userInfo' => 
            array (size=7)
              'id' => null
              'level' => null
              'name' => null
              'ip' => null
              'lastActiveTime' => null
              'lastLogTime' => null
              'authToken' => null
      protected 'aModules' => 
        array (size=0)
          empty
      private '_aModuleList' (Init) => 
        array (size=11)
          0 => string 'ApiChain' (length=8)
          1 => string 'App' (length=3)
          2 => string 'EventStack' (length=10)
          3 => string 'HashUtls' (length=8)
          4 => string 'Issue' (length=5)
          5 => string 'IM' (length=2)
          6 => string 'Model' (length=5)
          7 => string 'Operation' (length=9)
          8 => string 'Router' (length=6)
          9 => string 'SmartyMod' (length=9)
          10 => string 'User' (length=4)
      

  8.   

    【已解决】EventStack.php第151行,我把数组下标写错了。应当是:if (isset($this->_aEventStack[$iKey]["handler"]) && !$mCallback) {
                    echo $func = $this->_aEventStack[$iKey]["handler"];
                    echo 1;
                    $func($mCallback);
                } else {
                    echo 2;
                    $func(null);
                }望各位看官引以为戒