Jump to content

If statement inside recursive function


kongondo
 Share

Recommended Posts

I have been banging my head about this for a while so I reckoned let me pick your brains instead  O0
I have a recursive function pinched from SO that loops over and outputs some records...
 
<?php

function listProducts($productCat,$level=0) {

$result = wire('db')->query("SELECT id, product, productcat FROM products WHERE productcat='$productCat' ORDER BY subcat");
if($result->num_rows == 0) 
return;

echo "<ul class='sortable'>\n";
while (list ($id, $product) = $result->fetch_row()) {   

echo "<li id='item_{$id}'>\n";
echo "<div class='dd-handle'>{$product}</div>\n";

listProducts($id,$level+1);

echo "</li>\n";
}
echo "</ul>\n";

}
?>

<div> 
<h5>Products</h5>
<ul class="sortable"><?php echo listProducts(0);//call the function ?></ul> <!-- problem -->
</div> 

Code works just fine. However, what  I need to do is to conditionally output the <ul> in the function depending on whether records are found or not like so:

if($result->num_rows == 0) {
echo "<ul class='sortable'></ul>\n";// echo empty ul if no products found
}

else {
echo "<ul class='sortable'>\n";// echo opening ul tag if products found
}

This is because I am adding product items to the <ul> using jQuery. If there are no products, I need an empty <ul></ul> to append my product items to. If there are product items, no need to echo the empty <ul></ul>, just echo the opening <ul> tag and the function will close it properly later on. If I do it like this, the code doesn't work properly. If there are no results, I don't get my empty <ul></ul>. If there are records,  I am getting extra/unnecessary empty <ul></ul> after each <li></li>. I have tried different things including $result->fetch_array (); then doing an if against that but without success. If I manually add the empty <ul></ul> when I call the function (like in my example above) I will of course still get empty extra <ul></ul> when I call the function and there are records. It's either this or resorting to querying the db again outside the function to check if there are records and echoing empty <ul></ul> if there aren't...etc.

Hope this makes sense and thanks for your help. Sorry for the long-winded <ul>s!

Link to comment
Share on other sites

If I've understood right you only need to get rid of the <ul>...</ul> wrapping the initial function call and modify the if-statement inside the function just a little bit to let it proceed on the first round even if there are no records found. Like this:

<?php

function listProducts($productCat,$level=0) {

    $result = wire('db')->query("SELECT id, product, productcat FROM products WHERE productcat='$productCat' ORDER BY subcat");
    if($level > 0 && $result->num_rows == 0) return;
    
    echo "<ul class='sortable'>\n";
    while (list ($id, $product) = $result->fetch_row()) {   
        
        echo "<li id='item_{$id}'>\n";
        echo "<div class='dd-handle'>{$product}</div>\n";
        
        listProducts($id,$level+1);
        
        echo "</li>\n";
    }
    echo "</ul>\n";

}
?>

<div> 
    <h5>Products</h5>
    <?php echo listProducts(0);//call the function ?>
</div>

As a side note, I usually build a simple safety net when using recursive functions just to be on the safe side if (when) there's suddenly broken data in the database. Here that would mean adding one line at the beginning of the function:

// ~25 levels of product categories could be considered an error, I think.
// Use something big enough to allow any legitimate data but small enough to allow the server stay alive.
if($limit > 25) throw new WireException("Recursion gone wild");

While it's not necessary, it's a small price to pay for peace of mind :).

  • Like 3
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...