php鏈表,裝載器模式與調用入口保護
這是一個十分有趣的問題。三者相遇,會發生一種怪異的衝突。
當裝載器模式模式實現鏈表的不同操作的演算法之時,我們在鏈類表中是用$this傳入鏈表本身。結果,演算法中,無法刪除鏈表的head。
具體表現為,函數內部,刪除head成功,而傳回值則記遠是原始的head.
為什麼呢?原來就是調用入口保護在作怪。但如果細想一下,這個保護是必須的。否則,函數流程沒有返回的位置了。無法再繼續下去。
所以,演算法內部只能放棄刪除head的想法。如何?呢?請看以下代碼:
data=$data; } //問題就是出在這裡,因為這裡是調用入口,本節點自然不可以被刪除。 public function loadData($dataString,$className){ $obj=new $className(); $obj->loadDataString($dataString,$this); //print_r($this); //這裡是錯的。 } } class csStringAdapter{ public function loadDataString($dataString, csList $cl, $level=0){ $spliter=array("\r\n", ',',' '); $dataArray=explode($spliter[$level],$dataString); for($i=0,$j=count($dataArray);$i<$j;$i++){ $newNode=new csList(); $newNode->parent = $cl; $cl->childNodes[]=$newNode; $dataItems=explode(' ', $dataArray[$i]); if (strpos($dataArray[$i],$spliter[$level+1])!==false){ echo 1;// exit; $this->loadDataString($dataArray[$i],$newNode,$level+1); }else{ $newNode->data=$dataArray[$i]; } } if ((count($cl->childNodes)==1) && ($cl->data=='')){ //因為head節點是空節點,所以要刪除 $cl=$cl->childNodes[0];//這樣刪除head是不行的。 //print_r ($cl); //但這裡列印輸出的結果是正確的。 } } } $test = new csList(); $nodeStr='a,b,c,d,e'; $test->loadData($nodeStr,'csStringAdapter'); print_r($test); //這裡列印也是錯的。head總是空節點,即是無data,同時只有一個childNodes的節點?>
?
明白了PHP對調用入口的保護,也就是明白了,程式中函數調用需要從哪裡來,還回哪裡去,那麼,上面的代碼就好修改了。以下是修改後的代碼
data=$data; } //問題就是出在這裡,因為這裡是調用入口,本節點自然不可以被刪除。 public function loadData($dataString,$className){ $obj=new $className(); $obj->loadDataString($dataString,$this); //print_r($this); //這裡是對的。 } } class csStringAdapter{ public function loadDataString($dataString, csList $cl, $level=0){ $spliter=array("\r\n", ',',' '); $dataArray=explode($spliter[$level],$dataString); for($i=0,$j=count($dataArray);$i<$j;$i++){ $newNode=new csList(); $newNode->parent = $cl; $cl->childNodes[]=$newNode; $dataItems=explode(' ', $dataArray[$i]); if (strpos($dataArray[$i],$spliter[$level+1])!==false){ echo 1;// exit; $this->loadDataString($dataArray[$i],$newNode,$level+1); }else{ $newNode->data=$dataArray[$i]; } } if ((count($cl->childNodes)==1) && ($cl->data=='')){ //因為head節點是空節點,所以要刪除 //$cl=$cl->childNodes[0];//這樣刪除head是不行的。 //print_r ($cl); //但這裡列印輸出的結果是正確的。 //我們這樣修改:將子節點資料複製到父節點中,實際是放棄第一層子節點: $cl->data=$cl->childNodes[0]->data; $cl->childNodes=$cl->childNodes[0]->childNodes; for($i=0,$j=count($cl->childNodes);$i<$j;$i++){ $cl->childNodes[$i]->parent=$cl; } } } } $test = new csList(); $nodeStr='a,b,c,d,e'; $test->loadData($nodeStr,'csStringAdapter'); print_r($test); //經過這樣修改,一切就正確了。?>
?
?