Jump to content

Checking level


drisate

Recommended Posts

function check_level($id, $level){

    $check = @current(@mysql_fetch_assoc(@mysql_query("SELECT parent FROM page_categ WHERE id = '$id'")));
    $level++;

    if ($check != "0") {
        check_level($check, $level);
    } else {
        return $level;
    }

}

 

I am trying to check the level of a menu item

 

1 blablabla (Level 0)

2 blablabla (Level 0)

  3. blablabla (Level 1)

  4. blablabla (Level 1)

      5. blablabla (Level 2)

 

The last item (5) should return level 2

 

The function above is not recalling it self. It's only detecting the first level

Link to comment
Share on other sites

Without knowing what parameters are being passed to the function and what data is being returned from the database, there is no way for us to know what should and should not be returned. You will need to debug the code. However, because you combined multiple functions into the line to define $check, that cannot be done effectively. You are also suppressing errors which doesn't help either.

 

Lastly, when you do call check_level() subsequent times, the return value is not being used due to variable scope and a recursive function! Let me try to explain. When check_level() is called the first time $level has a value. If the check value doesn't equal 0 you make a subsequent call to check_value passing an incremented $level value. In the second running of check_value(), the $level value is a different variable than the one in the first running of the function due to variable scope. So, let's say that second call does have a check value of 0 and returns the $level. It is returning that value to the first funttion call - not to the original line that called the function. It is kind of difficult to explain. But here are a couple of examples

 

function getThree($input)
{
    if($input<3) {
        getThree(++$input;);
    } else {
        return $input;
    }
}

echo getThree(1); //Ouput: - nothing - 

 

function getThree($input)
{
    if($input<3) {
        $input = getThree(++$input;);
    }
    return $input;
}

echo getThree(1); //Ouput: 3 

 

Try running the following:

function check_level($id, $level=0)
{
    $query  = "SELECT parent FROM page_categ WHERE id = '$id'";
    $result = mysql_query($query);
    $record = mysql_fetch_assoc($result);
    $parent_id  = $record['parent'];
    
    //Echo info for debugging purposes
    echo "ID: $id<br />\n";
    echo "Level: $level<br />\n";
    echo "Parent ID: $parent_id<br />\n";
    
    if ($parent_id != "0")
    {
        $level = check_level($parent_id, ++$level);
    }
    return $level;
}

 

NOTE: The first call to check_level() will not require the second parameter since it is now defined in the function parameters.

Link to comment
Share on other sites

Well the table is made like this

 

id, name    , parent

________________

1, blablabla, 0

2, blablabla, 0

3, blablabla, 2

4, blablabla, 2

5, blablabla, 4

 

So the menu output should be

 

1 blablabla (Level 0)

2 blablabla (Level 0)

  3. blablabla (Level 1)

  4. blablabla (Level 1)

      5. blablabla (Level 2)

 

I need to know what the level of item 5 is

 

check_level('5', $level)

 

Should return 2

 

I tryed you code above but it's a never ending loop.

 

This is what the script should do

 

1. Check the parent number of 5.

2. Parent number is 4

3. Increment level 0 to 1

4. Check parent number of 4

5. Parent number is 2

6. Increment level 1 to 2

7. Check parent number of 2

8. Parent number is 0

9. Return increment level 2

 

Link to comment
Share on other sites

I already explained why your function would not work because of variable scope and recursion in your function. Although, it can be a difficult concept to understand. I also provided a revised function that should prevent those problems and it provides the ability for debugging if it still doesn't work. Did you even try the code I provided?

 

I will try to provide a more detailed explanation using the example you provided above, This is based upon your first posted code to explain why it did not work.

 

1. Check the parent number of 5. (iteration #1 of the function)

2. Parent number is 4

3. Increment level 0 to 1 (in iteration #1 of the function)

4. Check parent number of 4 (iteration #2 of the function)

5. Parent number is 2

6. Increment level 1 to 2 (in iteration #2 of the function)

7. Check parent number of 2 (iteration #3 of the function)

8. Parent number is 0

9. Return increment level 2 (to iteration #2 of the function)

 

In each iteration of the function $level is a different variable and the last iteration of the function returns the $level to the previous iteration and there is no way to return that value to the initial iteration and return to the originally calling line of code. You can either fix it as I shoed by returning the level to each iteration by using

    if ($parent_id != "0")
    {
        $level = check_level($parent_id, ++$level);
    }
    return $level;

 

Or, you could also pass $level by reference so you are dealing with the same $level on each iteration. This is kind of difficult to explain in a forum post as it deals with some unique issues concurrently. You can take a look at the manual dealing with variable scope:

 

http://php.net/manual/en/language.variables.scope.php

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.