функция вызова php с эхом изнутри функции - PullRequest
1 голос
/ 05 декабря 2011

Я боролся с этим часами и не могу найти никакой информации в сети. У меня есть функция create_header, которая выводит html, а затем динамически создает список категорий из базы данных, используя рекурсивную функцию (называемую render_tree). Эта функция использует echo для вывода соответствующего html.

Когда я пытаюсь запустить эту функцию с помощью функции create_header, она ничего не выводит. Я попытался включить функцию render_tree в функцию create_header, чтобы убедиться, что она доступна, но, очевидно, я все еще делаю что-то не так

create_header()
{
?> <html>...

<?php
$conn = db_connect();

function renderTree($parent = "0")
{
//Category Menu - Main recursive function. I'll asume '0' id is the root node
global $categoryNames;
global $childrenTree;

$children = $childrenTree[$parent];
if($parent != "0")
{
    if ($categoryNames[$categoryNames[$parent]] == 1)
    {
        if (count($children) == 0 && $categoryNames[$categoryNames[$parent]] == 2)
            echo "<a class='subexpandable' href='item_list.php?cat=$parent'>" . $categoryNames[$parent] . "</a>\n";
        if (count($children) == 0 && $categoryNames[$categoryNames[$parent]] == 1)
            echo "<a class='menu' href='item_list.php?cat=$parent'><h3 class='menuheader'>" . $categoryNames[$parent] . "</h3></a>\n";
        else
            echo "<h3 class='menuheader expandable'>" . $categoryNames[$parent] . "</h3>\n";
    }
    else
    {
        if (count($children) == 0)
            echo "<li><a href='item_list.php?cat=$parent'>", $categoryNames[$parent], "</a></li>\n";
        else
            echo "<li><a class='subexpandable' href='item_list.php?cat=$parent'>", $categoryNames[$parent], "</a></li>\n";
    }
}
if(count($children) > 0){ //If node has children
    if ($parent == "0")
        echo "<div class='arrowlistmenu'>\n";
    else
    {
        if ($categoryNames[$categoryNames[$parent]] == 2)
            echo "<ul style='margin-left: 15px' class='subcategoryitems'>\n";
        elseif ($categoryNames[$categoryNames[$parent]] == 1)
            echo "<ul class='categoryitems'>\n";
    }
    foreach($children as $child)
        renderTree($child);
    echo "</ul>\n";
}
//if($parent != "0") echo "</li>\n";
if($parent == "0") echo "</div>";
}

$result = $conn->query("SELECT category_id AS id, parent_category_id AS parent_id, category_name AS category, level AS level FROM sp_categories WHERE is_showing = 1 ORDER BY `order`,category_id");
$childrenTree = array(); //Will store an array of children for each parent
$categoryNames = array(); //Will store category name for each id
//We fill $childrenTree and  $categoryNames from database

while ($row = mysqli_fetch_array($result)){ 
list($id, $parent_id, $category, $level) = $row;
$categoryNames[(string)$id] = $category;
$categoryNames[(string)$category] = $level;
//$categoryNames[(string)$pid] = $parent_id;
$parent_id = (string)$parent_id;
//  echo $parent_id;
if(!array_key_exists($parent_id, $childrenTree)) 
    $childrenTree[$parent_id] = array();
$childrenTree[$parent_id][] = (string)$id;
}
renderTree();  //This renders the hierarchical tree
?>
<more html>

Эхо в нижней части $parent_id правильно выводит идентификаторы, поэтому я знаю, что он обращается к базе данных.

Edit: Изначально у меня была функция create_header внутри библиотеки html_fns.php и функция render_tree внутри библиотеки php_fns.php, чтобы попытаться отделить те функции, которые в большей степени отображали html, от функций, которые содержали большое количество php в их. Это привело к тому же результату, что и вложенность файла render_tree в create_header - я вложил его, чтобы убедиться, что он определен.

Cheers, Chris

1 Ответ

1 голос
/ 05 декабря 2011

Это выглядит так, потому что вы определяете одну функцию внутри другой (очень редко хорошая идея в PHP), ваша область видимости немного испорчена. (Определение метода renderTree () таким образом не дает ему какой-либо особой области, оно просто задерживает его определение до этой точки в коде, что не имеет никакого значения.)

В частности, часть, в которой вы определяете $ childrenTree, находится в области действия функции create_header (), поэтому это не глобальная переменная, и к ней нельзя получить доступ внутри renderTree ().

Я думаю, что лучшая структура кода значительно упростит отладку:

// Generally considered a good idea to prepare data before display
$childrenTree = get_nodes_from_db();
// At this point, you shouldn't need to access the DB any more
display_header($childrenTree);

function display_header($childrenTree)
{
    // ...
    renderTree($childrenTree);
    // ...
}

Если вы абсолютно настаиваете на использовании глобальной переменной для $ childrenTree вместо того, чтобы передавать ее таким способом, разделите код на эти три функции без хитрого вложения и добавьте глобальную переменную $ childrenTree вверху обоих get_nodes_from_db () и renderTree ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...