Логическая ошибка в функции PHP - PullRequest
0 голосов
/ 22 ноября 2011

Я пытаюсь создать навигационное меню, например

 <ul>
   <li>
     <ul>
...........
    </ul>
  </li>
 </ul>

из БД, с одним-единственным запросом. Но как только я выполняю следующую функцию, она не останавливается. (Кажется, есть логическая ошибка). Пожалуйста, посмотрите, что не так

<?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 Ответ

1 голос
/ 22 ноября 2011

Не уверен, что это проблема, но я бы предложил использовать 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...