PHP behaves strange when capturing 'return' value, how to over come?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kapro
    New Member
    • Aug 2008
    • 4

    #1

    PHP behaves strange when capturing 'return' value, how to over come?

    PHP behaves strange when capturing 'return' value, how to over come?

    when i echo the value inside the function, it works fine.
    if i return a value from the function, it return nothing... why?

    Assume, that the following is the table 'menu' and having the following fields(with values)
    Code:
    menuid		
    ======
    1		 
    2		
    3		 
    4		  
    5
    parentmenuid
    ==========
    0
    1
    1
    5
    1
    //php code
    [code=php]
    <?
    include "db.php";

    $returnval=trac e_child(1,4);
    echo $returnval;

    function trace_child($pa rent,$child)
    {
    $result = mysql_query('SE LECT * FROM menu
    WHERE parentmenuid='. $parent);

    while ($row = mysql_fetch_arr ay($result))
    {
    if($child==$row['menuid'])
    {
    return true; ///the problem is here.. if i put echo 'true'; then it works fine... why
    }
    else{
    trace_child($ro w['menuid'],$child);}
    }
    }

    ?>
    [/code]

    i wants to trace whether menu '4' is grandchild of menu'1' .
    please somebody help me...
    Last edited by Atli; Aug 7 '08, 08:57 PM. Reason: Added [code] tags
  • Atli
    Recognized Expert Expert
    • Nov 2006
    • 5062

    #2
    Hi. Welcome to Bytes!

    When you echo a Boolean value, you won't get "true" or "false". You will either get "1" if it is true, or simply nothing if it is false.

    You need to use the value, like:
    [code=php]
    if(functionCall ()) {
    echo "true";
    }
    else {
    echo "false";
    }
    [/code]

    P.S.
    Please use [code] tags when posting code examples.

    Comment

    • kapro
      New Member
      • Aug 2008
      • 4

      #3
      Originally posted by Atli
      Hi. Welcome to Bytes!

      When you echo a Boolean value, you won't get "true" or "false". You will either get "1" if it is true, or simply nothing if it is false.

      You need to use the value, like:
      [code=php]
      if(functionCall ()) {
      echo "true";
      }
      else {
      echo "false";
      }
      [/code]

      P.S.
      Please use [code] tags when posting code examples.

      Hi Mr. Atli,
      i have tried that too.
      still no use...
      Actually, when we look at the above code it seems very fine...
      But when we pass the function output to a variable i fails...( it is success when i use 'echo' instead of 'return')...

      Mr.Atli,
      Please do me a favour...
      create a table(menu) that i mentioned previously, and also the field values...
      now execute the above code(my php code)... Now u will know what i am trying to say...

      Comment

      • Atli
        Recognized Expert Expert
        • Nov 2006
        • 5062

        #4
        Ahh ok now I see.

        The problem is the recursive call in your function doesn't return it's value.

        Consider this:
        [code=php]
        function testFunc($value ) {
        if($value == 2) {
        return true;
        }
        else {
        ++$value;
        testFunc($value );
        }
        }

        var_dump(testFu nc(1));
        # Prints: NULL
        [/code]
        Now this function will check the value first, which is 1 in the first run. After the first if() fails, it increments and calls itself again. This time the value is 2, so it returns true.

        The problem there is that the second call is the only one to return anything. You don't do anything with the results returned by that call (The recursive call, where the function calls itself).

        As a result, the result is disregarded in the original call and the function returns NULL.

        To fix this, in my example, you would have to add the return keyword to the second call:
        [code=php]
        function testFunc($value ) {
        if($value == 2) {
        return true;
        }
        else {
        ++$value;
        return testFunc($value ); # Change is here
        }
        }

        var_dump(testFu nc(1));
        # Prints: bool(true)
        [/code]

        In your function, you would have to check the return value of the recursive call. If it is true, return it. If it is not, continue the while loop and return false once the loop has ended.

        Comment

        • kapro
          New Member
          • Aug 2008
          • 4

          #5
          Originally posted by Atli
          Ahh ok now I see.

          The problem is the recursive call in your function doesn't return it's value.

          Consider this:
          [code=php]
          function testFunc($value ) {
          if($value == 2) {
          return true;
          }
          else {
          ++$value;
          testFunc($value );
          }
          }

          var_dump(testFu nc(1));
          # Prints: NULL
          [/code]
          Now this function will check the value first, which is 1 in the first run. After the first if() fails, it increments and calls itself again. This time the value is 2, so it returns true.

          The problem there is that the second call is the only one to return anything. You don't do anything with the results returned by that call (The recursive call, where the function calls itself).

          As a result, the result is disregarded in the original call and the function returns NULL.

          To fix this, in my example, you would have to add the return keyword to the second call:
          [code=php]
          function testFunc($value ) {
          if($value == 2) {
          return true;
          }
          else {
          ++$value;
          return testFunc($value ); # Change is here
          }
          }

          var_dump(testFu nc(1));
          # Prints: bool(true)
          [/code]

          In your function, you would have to check the return value of the recursive call. If it is true, return it. If it is not, continue the while loop and return false once the loop has ended.
          Hi Mr.Atli,
          I was Very happy with your code when i when i got success for the above condition. But the program FAILS when it got morethan one child!
          for example:
          Condition: #2 (for Menu table)
          Code:
          menuid(field1)
          =====
          1
          2
          3
          4
          5
          
          parentmenuid(field2)
          ==========
          0
          1
          2
          2
          1
          now trace_child(2,4 )
          please check once again!
          thanks for kind response!

          Comment

          • Atli
            Recognized Expert Expert
            • Nov 2006
            • 5062

            #6
            What's your current code?

            Also, if I may suggest and alternate solution to this problem.

            Your current method of searching is somewhat wasteful.
            Consider if you had one top-level menu, which had 100 child menus, each of which had a 100 child menus of their own.

            If you were to try to match the root parent with the very last grandchild menu in that list, your search would have to go through every menu in the tree structure before it found a match.
            Given our above data, that would take 9,999 queries!

            My suggestion would be to search up from the child, looking for the parent, rather then your current method of searching down from the parent.

            We don't usually build fully functional solutions for people, trying instead to help them create the solutions themselves.
            But I found the best way to explain this properly would be to show you some code.

            So, consider this.
            [code=php]
            function findParent($par ent, $child)
            {
            // Set the starting point for our search
            $current = $child;

            // Loop until the current menu is false.
            // The root menu doesn't have a parent, so the parent of the root
            // will be a null value (0), which will be evaluated as false, thus
            // ending the loop.
            while($current)
            {
            // Query for the parent of the current menu
            $sql = "SELECT parent FROM menu WHERE child = $current";
            $result = mysql_query($sq l);
            $row = mysql_fetch_ass oc($result);

            // Replace the current menu with it's parent
            // so the search can continue from this point
            // in the next loop
            $current = $row['parent'];

            // Check if the parent is the one we are looking for.
            // If it is, the search is over and we return true
            if($current == $parent) return true;
            }

            // The loop has ended without finding the parent.
            // The search failed. Return false.
            return false;
            }
            [/code]
            This function would only ever have to execute an amount of queries less than or equal to the depth of the tree structure. Which in your case is only 2.

            Comment

            • kapro
              New Member
              • Aug 2008
              • 4

              #7
              Originally posted by Atli
              What's your current code?

              Also, if I may suggest and alternate solution to this problem.

              Your current method of searching is somewhat wasteful.
              Consider if you had one top-level menu, which had 100 child menus, each of which had a 100 child menus of their own.

              If you were to try to match the root parent with the very last grandchild menu in that list, your search would have to go through every menu in the tree structure before it found a match.
              Given our above data, that would take 9,999 queries!

              My suggestion would be to search up from the child, looking for the parent, rather then your current method of searching down from the parent.

              We don't usually build fully functional solutions for people, trying instead to help them create the solutions themselves.
              But I found the best way to explain this properly would be to show you some code.

              So, consider this.
              [code=php]
              function findParent($par ent, $child)
              {
              // Set the starting point for our search
              $current = $child;

              // Loop until the current menu is false.
              // The root menu doesn't have a parent, so the parent of the root
              // will be a null value (0), which will be evaluated as false, thus
              // ending the loop.
              while($current)
              {
              // Query for the parent of the current menu
              $sql = "SELECT parent FROM menu WHERE child = $current";
              $result = mysql_query($sq l);
              $row = mysql_fetch_ass oc($result);

              // Replace the current menu with it's parent
              // so the search can continue from this point
              // in the next loop
              $current = $row['parent'];

              // Check if the parent is the one we are looking for.
              // If it is, the search is over and we return true
              if($current == $parent) return true;
              }

              // The loop has ended without finding the parent.
              // The search failed. Return false.
              return false;
              }
              [/code]
              This function would only ever have to execute an amount of queries less than or equal to the depth of the tree structure. Which in your case is only 2.
              Mr. Atli,
              Thanks a ton man. It works fine now...
              thanks

              Comment

              Working...