PHP函数中的逻辑错误

时间:2011-11-21 22:18:14

标签: php mysql function mysqli prepared-statement

我要做的是,生成像

这样的导航菜单
 <ul>
   <li>
     <ul>
...........
    </ul>
  </li>
 </ul>
来自db的

,只有一个查询。但是一旦我执行了以下功能,它就不会停止。 (似乎存在逻辑错误)。请看看,出了什么问题

<?php

function generateMenu($parent, $level, $menu, $utype) {
    global $db;

    $tree = array();
    $stmt = $db->prepare("select id, parent, name FROM navigation WHERE menu=? AND user_type=?") or die($db->error);
    $stmt->bind_param("ii", $menu, $utype) or die($stmt->error);
    $stmt->execute() or die($stmt->error);

    $stmt->store_result();
    $meta = $stmt->result_metadata();

// the following creates a bind_result string with an argument for each column in the query
// e.g. $stmt->bind_result($results["id"], $results["foo"], $results["bar"]);
    $bindResult = '$stmt->bind_result(';
    while ($columnName = $meta->fetch_field()) {
        $bindResult .= '$results["' . $columnName->name . '"],';
    }
    $bindResult = rtrim($bindResult, ',') . ');';

// executes the bind_result string
    eval($bindResult);
    $stmt->fetch();
    $stmt->close();
    while (list($id, $parent, $name) = $results) {
        $tree[$id] = array('name' => $name, 'children' => array(), 'parent' => $parent);
        if (!array_key_exists($tree[$parent]['children'][$id])) {
            $tree[$parent]['children'][$id] = $id;
        }
    }

    print_r($tree);
}

?>

1 个答案:

答案 0 :(得分:1)

不确定这是否是问题,但我建议使用call_user_func_array代替eval来致电bind_result

$bindResult = array();
while ($columnName = $meta->fetch_field()) {
   // Needs to passed by reference, so that it creates the $results array correctly
   $bindResult[] = &$results[$columnName->name];
}
call_user_func_array(array($stmt, 'bind_result'), $bindResult);

编辑:您的问题是需要为每一行调用$sql->fetch(),而不是仅调用一次。代码永远循环,因为你继续阅读同一行。试试这个:

function generateMenu($parent, $level, $menu, $utype) {
    global $db;

    $tree = array();
    $stmt = $db->prepare("select id, parent, name FROM navigation WHERE menu=? AND user_type=?") or die($db->error);
    $stmt->bind_param("ii", $menu, $utype) or die($stmt->error);
    $stmt->execute() or die($stmt->error);

    $stmt->store_result();
    $meta = $stmt->result_metadata();

    $bindResult = array();
    $results = array();
    while ($columnName = $meta->fetch_field()) {
       // Needs to passed by reference, so that it creates the $results array correctly
       $bindResult[] = &$results[$columnName->name];
    }
    call_user_func_array(array($stmt, 'bind_result'), $bindResult);

    while ($stmt->fetch()) {
        list($id, $parent, $name) = $results;
        $tree[$id] = array('name' => $name, 'children' => array(), 'parent' => $parent);
        if (!array_key_exists($tree[$parent]['children'][$id])) {
            $tree[$parent]['children'][$id] = $id;
        }
    }
    $stmt->close();

    print_r($tree);
}