Home >Backend Development >PHP Tutorial > php链表,装载器方式与调用入口保护

php链表,装载器方式与调用入口保护

WBOY
WBOYOriginal
2016-06-13 13:02:34780browse

php链表,装载器模式与调用入口保护

这是一个十分有趣的问题。三者相遇,会发生一种怪异的冲突。
当装载器模式模式实现链表的不同操作的算法之时,我们在链类表中是用$this传入链表本身。结果,算法中,无法删除链表的head。
具体表现为,函数内部,删除head成功,而返回值则记远是原始的head.
为什么呢?原来就是调用入口保护在作怪。但如果细想一下,这个保护是必须的。否则,函数流程没有返回的位置了。无法再继续下去。
所以,算法内部只能放弃删除head的想法。如何实现呢?请看以下代码:

<?php error_reporting(E_ALL);
    
    class csList{
        public $data='';
        public $parent;
??????? public $childNodes=array();
        public function __construct($data=false){
            $this->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);$iparent = $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对调用入口的保护,也就是明白了,程序中函数调用需要从哪里来,还回哪里去,那么,上面的代码就好修改了。以下是修改后的代码

<?php error_reporting(E_ALL);
    
    class csList{
        public $data='';
        public $parent;
        public $childNodes=array();
        public function __construct($data=false){
            $this->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);$iparent = $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);$ichildNodes[$i]->parent=$cl;
                }
            }
        }
    }
    
    $test = new csList();
    $nodeStr='a,b,c,d,e';
    $test->loadData($nodeStr,'csStringAdapter'); 
    print_r($test); //经过这样修改,一切就正确了。

?>

?

?

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn