|<<>>|234 of 293 Show listMobile Mode

PHP Gets Closures / Lambda Functions

Published by marco on

The recently-published RFC: Lambda functions and closures by Christian Seiler & Dmitry Stogov (PHP) has all the details about a patch for PHP that adds support for closures to PHP 5.3 and higher. It looks like the proposal was initially made in December of 2007 and the process lasted about half a year. Compare and constrast with Java’s long struggle to get closures, which isn’t over by half[1].

The syntax is pretty straightforward, though not as elegant as the lambda syntax adopted by C# (and likely others of whose syntax I’m not aware, like Ruby or Python). Reference variables are supported, but copy-by-value is the default for local variables (as is the norm for PHP). Local variables referenced in the closure must be listed explicitly for two reasons:

  1. The patch is supposed to be low-impact in both syntax and compiler changes; automatic detection of referenced local variables as they are typically used in PHP[2] was deemed an unrealistic goal.
  2. Frameworks tend toward variable-variable tricks ($$var), hiding variable references in text and putting variable references into arrays, all of which would require more sophisticated measures to detect.

A lambda construct has a nameless function followed by a parameter list followed by an optional use clause that lists the local variables that may be referenced from the closure. A closure defined within a class automatically includes a reference to $this.[3] Here’s an example of a replacer function that defines an anonymous replacer function—customized for the parameters passed to the outer method—which is, in turn, passed to array_map.

function replace_in_array ($search, $replacement, $array) {
  $map = function ($text) use ($search, $replacement) {
    if (strpos ($text, $search) > 50) {
      return str_replace ($search, $replacement, $text);
    } else {
      return $text;
    }
  };
  return array_map ($map, $array);
}

The closure header and closing brace are highlighted in the example above; the body of the closure is just normal PHP code with the additional restriction that the scope is limited to the contents of the parameters and “use” clauses.

All in all, it seems like a solid addition to PHP and should lead to cleaner code for those using the latest version.


[1] Distance toward the goal of getting closures in Java was gauged solely on a few half-hearted Google searches that failed to turn up any official feature list as late as June of 2008 (Java.Net Forums). One of the linked articles pinned the odds of closures appearing in Java 7 at 70% in January of 2008. Once that hits 100%, they would still have to actually be implemented.
[2] Turn off this behavior by defining the closure as a static function.