PHP多次调用带有静态变量的递归函数会返回不正确的数据

时间:2015-07-24 05:53:10

标签: php variables static

我有返回元素数量的函数:

<?
function get_path($node, $check=null) { 

static $count;

$result = mysql_query('SELECT NAME, PARENT_ID FROM b_disk_object  
                       WHERE ID="'.$node.'";'); 
$row = mysql_fetch_array($result); 

    if ($row['NAME']!='') { 
            $path=$row['NAME'];

            if($path==$check){
                $count++;
                $path=get_path($row['PARENT_ID'],$check);
            }

    $path=get_path($row['PARENT_ID'],$check);
    }
return $count;

} ?>

当我调用该函数一次时,这可以正常工作,但是如果我多次调用它会返回不正确的数据 - 它会增加上一次函数调用的计数结果。例如,当我第一次调用它时,它返回5,当我再次调用它时,而不是返回2,它返回7.

ID         NAME                        PARENT_ID 
1         Sales                             
2         Marketing                      1
3         sales_optimiztaion.txt         2
4         Quotes                         6
5         list.xls                       4
6         General data   
7         file.odt                       1

我想计算多少个文件,例如,Sales文件夹包含 - 在这种情况下 - 2(sales_optimiztaion.txt和file.odt)。

3 个答案:

答案 0 :(得分:1)

当您从外部调用函数时,似乎希望将$count重置为0,但在进行递归调用时保持其值。但是静态变量无法区分调用函数的位置,它们始终保持其与前一次调用的值。

使用带有默认值的函数参数,而不是静态变量。

function get_path($node, $check=null, $count = 0) { 

    $result = mysql_query('SELECT NAME, PARENT_ID FROM b_disk_object  
                           WHERE ID="'.$node.'";'); 
    $row = mysql_fetch_array($result); 

    if ($row['NAME']!='') { 
        $path=$row['NAME'];

        if($path==$check){
            $count++;
            $count = get_path($row['PARENT_ID'],$check, $count);
        }

        $count = get_path($row['PARENT_ID'], $check, $count);
    }
    return $count;
}

我认为你可以用一个简单的循环而不是递归来写这个:

function get_path($node, $check = null) {
    $count = 0;
    while (true) {
        $result = mysql_query("SELECT NAME, PARENT_ID
                                FROM b_disk_object
                                WHERE ID = '$node'");
        $row = mysql_fetch_array($result);
        if (!$row) { // Reached the end of the parent chain
            return $count;
        }
        if ($row['NAME'] == $check) {
            $count++;
        }
        $node = $row['PARENT_ID'];
    }
}

答案 1 :(得分:0)

使用常规变量作为其他指出。将初始值设置为0.代码看起来很好;是基本的;我无法想象它为什么不起作用。什么不起作用?你跟踪过你的节目吗?跟踪会向您揭示问题的根源。

使用类似这样的范例

       if($path==$check){
            $count++;
            $count = $count + get_path($row['PARENT_ID'],$check);
        }

答案 2 :(得分:0)

我知道这是一个迟来的答案。 您可以像这样从外部或内部调用函数并为其设置变量来重置标志:

<?
function get_path($node, $check=null, $reset=true) { 

static $count;

if ($reset)
    $count = 0;

$result = mysql_query('SELECT NAME, PARENT_ID FROM b_disk_object  
                       WHERE ID="'.$node.'";'); 
$row = mysql_fetch_array($result); 

    if ($row['NAME']!='') { 
            $path=$row['NAME'];

            if($path==$check){
                $count++;
                $path=get_path($row['PARENT_ID'],$check, false); //do not reset
            }

    $path=get_path($row['PARENT_ID'],$check, false); //do not reset
    }
return $count;

} ?>