Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 10 of 10
  1. #1
    New to the CF scene
    Join Date
    Mar 2013
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Question Calling for help in order to understand a Callback function!

    Hello, I'm learning PHP and I came across with an example of what a callback could be, and it's driving me crazy, for an entire week now!

    In order to understand the example above, I previously have to learn what a 'Variable Function' is because it is used here as you'll see.

    So, basically, the $functions variable is a 'variable function' because it contains the names of other functions in an array, one is built in and the other two are user-defined.

    Next, since this variable function is passed as a parameter into the validate function, which later calls the functions contained in the passed variable function ($functions) is why this is called a callback function! Right?

    Here is my working example:

    PHP Code:
    <?php
    function validate($data$functions) {
        
    $valid true;
        foreach (
    $functions as $function) {
            
    $valid $valid && $function($data);
        }
        return 
    $valid;
    }

    function 
    is_at_least_18($number) {
        return 
    $number >= 18;
    }

    function 
    is_less_than_62($number) {
        return 
    $number 62;
    }

    $age 25;
    $functions = array('is_numeric''is_at_least_18''is_less_than_62');
    $is_valid_age validate($age$functions); // true

    var_dump($is_valid_age);
    ?>
    In a sense, the validate() function returns TRUE (boolean) if all the functions in the array (variable function) are tested TRUE, but, if there is a least one of these functions which is false, then the validate function return false as a whole.

    [BOLD]I think I pretty much understand how this works, but still, there are some gray zones in my mind:[/BOLD]

    1. Why, before the foreach loop, is needed to set '$valid = true'?

    2. How to read in plain english what's going on inside the loop. I know that for each iteration this is like:

    First iteration: $valid = $valid && is_numeric($data);
    Second iteration: $valid = $valid && $is_at_least_18($data);
    Third iteration: $valid = $valid && $is_less_than_62($data);

    But why the '$valid &&' thing. Why not just remove that and the first $valid = true and then just assign the result of each iteration to the $valid variable.


    I know, I'm pretty close, well... maybe close to get back to square one!

    Thanks in advance and sorry my bad English.
    Last edited by motherpeople; 03-17-2013 at 04:47 AM.

  • #2
    New Coder
    Join Date
    Dec 2011
    Posts
    61
    Thanks
    4
    Thanked 10 Times in 10 Posts
    You're not testing anything, $valid is set to true because you have it set as true in the function.

    Here maybe this will help:

    PHP Code:
    <?php
    function validate($people$conditions$value) {
       
        foreach (
    $people as $key => $value) {
           if ( 
    $value <= 18 
           {
               echo 
    $key $conditions[0] . "<br />";
               
    $value true;
           } 
           elseif (( 
    $value 18 ) && ( $value 62 ))
           {
               echo 
    $key $conditions[1] . "<br />";
               
    $value true;
           }
           else
           {
               echo 
    $key $conditions[2] . "<br />";
               
    $value true;
           }
                  
        }
        
        return 
    $value;
      
    }


    $value false;
    // Numeric Array
    $conditions = array(' is less than or equal to 18',  ' is between 18 and 62'' is equal or older than 62');
    // Associative Array
    $people = array("John" => 48"Sabrina" => 16"Robert" => 85);

    $value validate($people$conditions$value);

    if (
    $value) {
        echo 
    "One of the conditions has been met.";
    }
    ?>
    Last edited by Strider64; 03-17-2013 at 06:33 AM.

  • #3
    New to the CF scene
    Join Date
    Mar 2013
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Strider64 View Post
    You're not testing anything, $valid is set to true because you have it set as true in the function.
    Hi. The validate function is actually testing the $age value and works. If you start to remove code the application breaks. Everything seems to be in a place for a reason. I don't know why do you say that is not testing anything... more explanation needed.
    Last edited by motherpeople; 03-17-2013 at 06:34 AM. Reason: misspelling

  • #4
    New to the CF scene
    Join Date
    Mar 2013
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Cool

    Quote Originally Posted by Strider64 View Post
    You're not testing anything, $valid is set to true because you have it set as true in the function.

    Here maybe this will help:

    PHP Code:
    <?php
    function validate($people$conditions$value) {
       
        foreach (
    $people as $key => $value) {
           if ( 
    $value <= 18 
           {
               echo 
    $key $conditions[0] . "<br />";
               
    $value true;
           } 
           elseif (( 
    $value 18 ) && ( $value 62 ))
           {
               echo 
    $key $conditions[1] . "<br />";
               
    $value true;
           }
           else
           {
               echo 
    $key $conditions[2] . "<br />";
               
    $value true;
           }
                  
        }
        
        return 
    $value;
      
    }


    $value false;
    // Numeric Array
    $conditions = array(' is less than or equal to 18',  ' is between 18 and 62'' is equal or older than 62');
    // Associative Array
    $people = array("John" => 48"Sabrina" => 16"Robert" => 85);

    $value validate($people$conditions$value);

    if (
    $value) {
        echo 
    "One of the conditions has been met.";
    }
    ?>
    Sorry, Even when I appreciate your time and effort very much, I think you've missed the point here. hehe.

    What I'm trying to do is to understand the example exposed before, I don't need to refactor the application or write anything else. I just need help to fully understand why everthing was coded the way it was.

    To give you some hint I was asking how to read, for example, the iterations in the foreach loop...

  • #5
    Regular Coder
    Join Date
    May 2011
    Posts
    239
    Thanks
    1
    Thanked 56 Times in 55 Posts
    Quote Originally Posted by motherpeople View Post
    But why the '$valid &&' thing. Why not just remove that and the first $valid = true and then just assign the result of each iteration to the $valid variable.
    You could remove the first $valid = true and the '$valid &&' thing, but you must return false on the first validation error.

    e.g.

    PHP Code:
    function validate($data$functions
    {
            foreach (
    $functions as $function)
            {
                    if (!
    $function($data))
                            return 
    false;
            }
            return 
    true;


  • #6
    Senior Coder
    Join Date
    Feb 2011
    Location
    Your Monitor
    Posts
    4,089
    Thanks
    51
    Thanked 506 Times in 493 Posts
    Quote Originally Posted by motherpeople View Post
    PHP Code:
    <?php
    function validate($data$functions) {
        
    $valid true;
        foreach (
    $functions as $function) {
            
    $valid $valid && $function($data);
        }
        return 
    $valid;
    }
    In a sense, the validate() function returns TRUE (boolean) if all the functions in the array (variable function) are tested TRUE, but, if there is a least one of these functions which is false, then the validate function return false as a whole.

    I think I pretty much understand how this works
    You shouldn't, I've just had my head screwed by it.

    This line:
    $valid = $valid && $function($data);

    I've no idea whats going on there and it may be a legitimate php technique but it is not doing anything useful or easy for you as a learner to understand. Change it to this:
    $valid = $function($data);

    return $valid does exactly that. As soon as you hit the return line, the function exits and returns the value of the variable.

    As for the $valid = true thing, you should set your default / desired result and ONLY change it / act on it if you need to.
    My helpful sig is on vacation trying to loose some weight. It got a bit fat and caused a few problems but it will be back at some point!

  • Users who have thanked tangoforce for this post:

    motherpeople (03-19-2013)

  • #7
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    $valid = $valid && $function($data); is a boolean assignment to the $valid variable based on two possible results. It is simply checking if its valid and the current function returns true. If either case is false, than $valid is false. If you loop through every record, this is needed instead of $valid = $function($data); since this will return the results of only the last element in the hashtable.

    Perhaps a better method to use is a simple while:
    PHP Code:
    while ($valid && ($cur current($functions)))
    {
        
    $valid $cur($data);
        
    next($functions);

    IMO its not necessary to continue processing in the event of any failure, so I terminate as a part of the loop condition instead.

    For the first question: $valid must be set to true prior to the loop. Without it, any iteration within the foreach will set $valid to false regardless of the result of $function. If you provide it with no functions, than it will return true, which is correct.
    For the second, looks like I answered that with the above.

    This behaviour is similar to the use of the filter_var family of functions, which do include a validate check for integer and values between a given min and max range.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • Users who have thanked Fou-Lu for this post:

    motherpeople (03-19-2013)

  • #8
    New to the CF scene
    Join Date
    Mar 2013
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Fou-Lu View Post
    $valid = $valid && $function($data); is a boolean assignment to the $valid variable based on two possible results. It is simply checking if its valid and the current function returns true. If either case is false, than $valid is false. If you loop through every record, this is needed instead of $valid = $function($data); since this will return the results of only the last element in the hashtable.

    Perhaps a better method to use is a simple while:
    PHP Code:
    while ($valid && ($cur current($functions)))
    {
        
    $valid $cur($data);
        
    next($functions);

    IMO its not necessary to continue processing in the event of any failure, so I terminate as a part of the loop condition instead.

    For the first question: $valid must be set to true prior to the loop. Without it, any iteration within the foreach will set $valid to false regardless of the result of $function. If you provide it with no functions, than it will return true, which is correct.
    For the second, looks like I answered that with the above.

    This behaviour is similar to the use of the filter_var family of functions, which do include a validate check for integer and values between a given min and max range.
    Thank you very much guys, it is screwing my mind too, tangoforce.

    After all, the problem is not my understanding at all of what a callback, variable or anonymous functions are but the particular technique used in this example within the foreach loop, or, to a greater extent, how a foreach loop works at all.

    Fou-Lu, you're right, it makes no sense to keep processing the foreach loop after a variable function tests FALSE. BUT! here is an interesting behavior I wasn't aware:

    For example, say you set the variable $age = 14;

    1. This will pass the first iteration (is_numeric)
    2. Obviously, will fail the second iteration (is_at_least_18) which is not.
    3. And here is my surprise, it will not test the $age value for the third iteration at all (is_less_than_62) when the previous variable function tests FALSE. I mean, this third variable function automatically return FALSE in such scenario.

    I've tested this with a debuger with breakpoints properly set, and php never seems to be getting into the third variable function, it just tests FALSE (same happen with other functions if you add more to the array of functions).

    # How do you describe this behavior or why this is happening?

    # Why in every iteration $valid is not the value settled right before the loop (always TRUE) but instead, it is just the value settled by the last boolean assignment inside the loop?

    Anyways, I know this may not be important, at least at this point in my learning process, but this is now just a personal matter! i cannot sleep at night, no joke, I have to fully make sense of this!

  • #9
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    That's correct.
    Since you are evaluating and && assignment, all sides need to be true. As soon as $valid is flagged as false, the equation becomes false && anything which is always false. So it doesn't proceed to the next instruction to call the function. It will still loop though, which is why I suggest the while.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • #10
    Senior Coder
    Join Date
    Feb 2011
    Location
    Your Monitor
    Posts
    4,089
    Thanks
    51
    Thanked 506 Times in 493 Posts
    Quote Originally Posted by Fou-Lu View Post
    $valid = $valid && $function($data); is a boolean assignment to the $valid variable based on two possible results. It is simply checking if its valid and the current function returns true. If either case is false, than $valid is false.
    I didn't know about that after all these years!

    Thanks Fou
    My helpful sig is on vacation trying to loose some weight. It got a bit fat and caused a few problems but it will be back at some point!


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •