为什么没有静态这种方法不起作用?

时间:2014-04-25 09:41:14

标签: php methods

以下方法将数组排序为层次结构。

如果你运行一次就可以正常工作,但是如果用不同的nodes_array多次调用该方法,它就不会清除静态数组,因此会将它附加到第一个nodes_array。

// ORDER NODES
public function order_nodes_function($nodes_array,$parent_id, $level) { 
    static $j=0;
    static $ordered_nodes_array=array();
    for($t=0;$t<count($nodes_array);$t++){
        if($nodes_array[$t]['parent_id']==$parent_id){
            $ordered_nodes_array[$j]=$nodes_array[$t];
            $ordered_nodes_array[$j]['depth']=$level;
            $j++;
            $this->order_nodes_function($nodes_array, $nodes_array[$t]['node_id'], $level+1);
        }
    }
    return $ordered_nodes_array;
}

因此我尝试构建一个不使用静态变量的方法,但它不起作用,任何想法我做错了什么?...

// ORDER NODES
public function order_nodes_function($nodes_array,$parent_id,$level,$ordered_nodes_array,$j) { 
    for($t=0;$t<count($nodes_array);$t++){
        if($nodes_array[$t]['parent_id']==$parent_id){
            $ordered_nodes_array[$j]=$nodes_array[$t];
            $ordered_nodes_array[$j]['depth']=$level;
            $j++;
            $this->order_nodes_function($nodes_array, $nodes_array[$t]['node_id'], $level+1, $ordered_nodes_array, $j);
        }
    }
    return $ordered_nodes_array;
}   

2 个答案:

答案 0 :(得分:0)

我认为$ j没有传递给这个函数。

同样,order_nodes_function似乎在两个例子中完全不同

答案 1 :(得分:0)

static变量只初始化一次,其状态保持在整个程序运行中。所以当你使用

static $ordered_nodes_array=array();

它只被初始化为一个空数组,从现在开始每次在此范围内引用$ordered_nodes_array时,您使用的是具有最后一个设置值的变量。这就是为什么它不会在后续调用中重置的原因。

在第二个示例中,您将$ordered_nodes_array的值传递给递归函数,但在另一个范围内操作它不会更改原始函数中的数组(因为只传递值,而不是引用 - 实际上,这会在内存中创建两个不同的变量。

您有不同的选择:

  1. 捕获递归函数的返回值并将其添加到返回值。这样的事情(我不知道你的实现细节):

    $orderd_nodes_array[] = $this->order_nodes_function(
        $nodes_array, 
        $nodes_array[$t]['node_id'], 
        $level+1, 
        $ordered_nodes_array, 
        $j
    );
    
  2. 将数组的引用传递给递归函数而不是值:

    public function order_nodes_function(
         $nodes_array,
         $parent_id,
         $level,
         &$ordered_nodes_array,
         $j
    ) { ... }
    

    请注意&之前的$ordered_nodes_array符号。它告诉解释器变量应该通过引用而不是值传递。这意味着它将作为一个变量保留在内存中,并且在此函数内部进行的任何修改都将对原始数组产生影响。

  3. 在您的班级中创建一个属性并操纵该属性。

    class myClass
    {
    
         protected $orderedNodeList;
    
         public function __construct()
         {
             $this->orderedNodeList = array();
         }
    
         public function orderNodes(...)
         {
             $this->orderedNodeList[] = ...;
         }
    }
    
  4. 通过这种方式,您可以访问班级内任何位置的有序列表。只要您使用不同的对象来排序列表,有序的对象就永远不会混淆。