skip to Main Content

I am learning PHP using reviewing some complete PHP projects. (I know that this is a bad way, but my goal is not to be a PHP programmer!) Anyway, I faced with the following function that is weird a little to me:

function filterIt($filter): callable {
    return function ($value) use ($filter) {
        return filter_var($value, $filter) !== false;
    };
}

I don’t know what this function do and why it has been witter in such a way that a function is inside of another function! inner function returns something and main function also. Why we need such complicated function? or maybe one can make it simpler?

For this reason I want to write isEven() function as callable function like above. But I have no idea!

I don’t know what that function do, but by mimicking from that:

function isEven($num): callable {
    return function () use ($num) {
        return $num % 2 == 0;
    };
}

I couldn’t debug this using var_dump or print_r .

2

Answers


  1. Not sure how you are calling this in you’re test, but as the function is actually returning a callable you would be able to debug it once you run it like this:

    <?php
    
    function isEven($num): callable {
        return function () use ($num) {
            return $num % 2 == 0;
        };
    }
    
    var_dump(isEven(14)());
    
    Login or Signup to reply.
  2. IMO the summary of the filterIt() function is "give me an anonymous function that filters based on $filter", and then that callable is likely passed somewhere else to be applied. I would venture to guess that the author wrote this function as a shorthand so that they did not need to write out the anonymous function definition over and over for different values of $filter.

    Below is a simplified example of such behaviour:

    class ExampleCollection {
        protected $filters = [];
        
        public function __construct(protected array $items) {}
        
        public function addFilter(callable $filter) {
            $this->filters[] = $filter;
        }
        
        public function getFiltered() :Generator {
            foreach($this->items as $item) {
                foreach($this->filters as $filter) {
                    if( $filter($item) ) {
                        continue 2;
                    }
                }
                yield $item;
            }
        }
    }
    
    function makeMultipleFilter(int $value) :callable {
        return function($a)use($value) {
            return $a % $value === 0;
        };
    }
    
    $c = new ExampleCollection([1,2,3,4,5,6,7,8,9,10]);
    
    // add filters to exclude multiples of 3 and 4
    $c->addFilter(makeMultipleFilter(3));
    $c->addFilter(makeMultipleFilter(4));
    
    foreach($c->getFiltered() as $item) {
        printf("Got: %dn", $item);
    }
    

    Output:

    Got: 1
    Got: 2
    Got: 5
    Got: 7
    Got: 10
    

    But I agree with Chris Haas’ comment that the author’s intent is not always obvious and is best asked of them, if possible. Further to that, not all code is exemplary, even if someone exemplary happens to have written it. Everyone writes themselves into a corner sometimes and has to resort to a confusing and/or ugly piece of code to get around it. Which is not to say that this is what that is, though it is somewhat confusing on first read.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search