欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

有关PHP回调函数的乌云。

程序员文章站 2022-03-15 17:45:02
...
本人较菜,请问各位侠士,如何在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

addEvent(    "DATA_REQUEST",    serialize(array(        array(            "request" => "settingDaemon"        )    )),    $fGetSettings,    null);?>




/EventStack.php
_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) {        //移除指定的观察者    }}  ?>

回复讨论(解决方案)

还是那样,连错误信息都不给全!

$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] =>                 )        )    [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] =>                         )                )            [scope] =>             [timestamp] => 1383634959        ))

还是那样,连错误信息都不给全!

$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] =>                 )        )    [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] =>                         )                )            [scope] =>             [timestamp] => 1383634959        ))



板大。您好,我把所有代码都贴出来,您就帮我解决下吧。

文件:app/welcome.php

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

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 "_________________________________________________>
"; foreach ($this->_aEventStack as $key => $value) { //if (in_array($value["stamp"], array("NOTICE", "WARNING", "ERROR", "ISSUE_TRACK"))) { echo "Stackid: $key Stamp ".$value["stamp"]." Backtrace ".$value["value"]." TIMESTAMP ".date("h:m:s",$value["timestamp"])."
"; //} } } ##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 157

Call 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


文件:Model.php

 $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;		}	}}?>

文件:App.php

getController();		if (in_array($sApp, $aAppAvailableList)) {			$this->_sApp = $sApp;			$sFilePath = "module/app/".$sApp.".php";			if (is_file($sFilePath) && is_readable($sFilePath)) {				require_once($sFilePath);			}		}	}}?>

你给全错误信息不经行了吗?
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"]; 放到条件分支外面吧?

你给全错误信息不经行了吗?
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"]; 放到条件分支外面吧?


我把代码改成这样,还是上面的错误。

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);			}		}	}

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)