6

I am beginning the process of moving code over to PHP 5.3 and one of the most highly touted features of PHP 5.3 is the ability to use closures. My understanding of closures is that they allow anonymous functions, can be assigned to variable names, and have interesting scoping abilities.

From my point of view the only seeming benefits in real world applications is the reduction of clutter in the namespace because closures are anonymous.

Am I wrong in this?

Should I be trying to put closures wherever I code?

EDIT:

I have already read this post on Javascript closures.

Patrick
  • 2,922
  • 2
  • 21
  • 24

3 Answers3

6

First off: Closures are not everything you describe as such. The concept of functions as first-class objects is related - although pretty much a prerequisite for closures - and anonymous functions are not really related (you usually have both in the same languages, but still, neither is required for the next).

I have come to the conclusion that to appreciate closures and to put them to good use, one needs to adopt a slightly more functional mindset. For example: When using higher-order functions (functions that return functions), the need for closures arises quite often (basically, every time the returned function needs to access the higher order function's arguments) and they are in fact the most natural solution. If you're writing a class to serve as an accumulator factory instead of a higher-order function, of course the closure won't fit in.

As a concrete example: I'm just writing a (small-ish, limited, kind-of) parser generator for XML defined in some relatively weird (but luckily, simple - XML abused as database, the kind of job JSOn or YAML does better) XSD offshot. The parsers returned are functions and about every one of the parsers is a closure (closing over the schema representation by which it parses). I'd rather not type up classes for all of this.

  • I'm not sure why I would create functions that would return functions. That may be why I'm not seeing the benefit? – Patrick Feb 01 '11 at 17:01
  • 3
    @Patrick: Yes. As I wrote, seeing the point in closures (or most other tools from the functional programming world) requires some getting-used-to-it and practice to learn how to apply them. Of course it does - can a programmer who doesn't know the basics of OOP see the benefit of inheritance? No. Likewise, if you have little/no experience with functional programming, you propably can't apply closures. Perhaps you should learn a functional language? –  Feb 01 '11 at 17:04
  • ok, that makes sense. I just wanted to make sure I wasn't missing the point, and so I guess I'll read up on functional programming to get up to speed. thanks – Patrick Feb 01 '11 at 18:14
0

As a guy whose responsibility among other things is unit testing in php using PhpUnit, Closures are also you great friend for testing a code which was not written in the best regards of test.

About two months ago I took over a team who had been developing a project with no unit tests what so ever and decided to dedicate a few programmers to learn how to unit test and write the tests. The project had service locator all over it, and I had to find a solution on how to solve the problem and with the help of a SO user Elias Van Ootegem I was able to.


As mentioned in the post, you can also simulate parameters passed and returned through a reference.

Should you have a function to test:

public function ReturnIntAndChangeOutputParameter(&$outputParameter = false)
{
    $outputParameter = true;
    return 10;
}

You can use callback to simulate the parameter return:

$function = function(&$outputParameter)
{
    $outputParameter = true;
    return 10;
}

$classMock
    ->expects(/* */)
    ->method('ReturnIntAndChangeOutputParameter')
    ->will($this->returnCalback($function));

In fact, when writing unit tests, this is the only way how to do that, PhpUnit otherwise converts all variables to be passed by value even if the definition is pass by reference.

Andy
  • 10,238
  • 4
  • 25
  • 50
0

A primary reason to use closures in PHP is to reduce dependencies between objects. For example:

Route::get('help', function () {
  return View::make('site.help');
});

Why should Route know about View? Sure, I could pass 'site.help' into Route::get, but then Route would be tied to View. Using the closure helps me to keep the classes independent.

This is similar to the way Wordpress uses anonymous callbacks in it's Plugin API. That simple mechanism IMO is what made Wordpress plugins so wildy successful - because the Wordpress framework knows nothing about the plugins, yet the plugins can change anything within the CMS framework.

This is similar to my answer Purpose of Closure Style in Laravel/PHP?

Charlie Dalsass
  • 123
  • 1
  • 5