PHP 5.3 and Closures
I'm fairly excited because as of only a week or so ago I found the closures rfc, and not only did I find that the rfc has a working patch, apparently it's already in PHP 5.3.
You see, apparently it's not good enough that we get name spaces and late static binding, oh no, we get closures too!
I downloaded the Win32 snapshot from PHP snapshots page and indeed, closure support was included.
<?php $closure = function ($args) use ($global) { /*Body*/ }; ?>
According to the rfc, one must manually define external variables used within a function, however in my own tests you can still use the global keyword. The difference between the two is the use statement preserves the value of $global at creation and the global keyword would work as you would expect it to with a normal function. For example:
<?php $global = "Global Variable"; $closureUse = function ($arg) use ($global) { echo $global . " - " . $arg; }; $closureGlobal = function ($arg) { global $global; echo $global . " - " . $arg; }; echo "Basic Closure Tests\n"; echo "-------------------\n\n"; echo "\$closureUse('test'): "; $closureUse('test'); echo "\n"; echo "\$closureGlobal('test'): "; $closureGlobal('test'); echo "\n"; echo "\n"; echo "Global Closure Tests\n"; echo "--------------------\n\n"; $global = "Global Variable (Changed)"; echo "\$closureUse('test') (changed \$global): "; $closureUse('test'); echo "\n"; echo "\$closureGlobal('test') (changed \$global): "; $closureGlobal('test'); echo "\n"; ?>
Would output:
Basic Closure Tests
-------------------
$closureUse('test'): Global Variable - test
$closureGlobal('test'): Global Variable - test
Global Closure Tests
--------------------
$closureUse('test') (changed $global): Global Variable - test
$closureGlobal('test') (changed $global): Global Variable (Changed) - test
You can, as well, return references with a closure by putting the & between the function keyword and the parenthesis.
<?php $closureReturnsReference = function & ($args) use ($global) { /*Body*/ }; ?>
Just one of many shiny fancy things to look forward to in PHP 5.3.
Edit 7/23/2008:
I should mention to the people that trashed my examples on reddit, I'm sorry for assuming you knew what closures were and the the real world uses of them. I will try to refrain from giving a concise example of how a new language feature interacts with existing features and conventions, especially in PHP where things are a bit disorganized.

David Dashifen Kees:
You know … we probably shouldn’t get this excited over programming language enhancements….
21 July 2008, 6:34 pmDaniel Cousineau:
Nonsense!
21 July 2008, 6:54 pmsapphirecat:
I just messed around with it a bit, and discovered this:
$g2 = 2; $closureReadOnly = function () use ($g2) { echo ++$g2 . "\n"; }; // Note that we take a *reference* to $g2 this time: $closureReadWrite = function () use (&$g2) { echo ++$g2 . "\n"; }; $closureReadOnly(); // 3 $closureReadOnly(); // 3, but would be 4 in JavaScript $closureReadWrite(); // 3 $closureReadWrite(); // 4 echo $g2 . "\n"; // 4 $closureReadOnly(); // 3 (still has private copy)So they seem to have taken the usual half-broken approach: you can have read-only closures which are immune to changes to a global variable, or you can have read-write closures which remember changes, but those changes leak back into the global variable.
Fortunately, there’s a simple workaround. If you create a read-write closure inside a function, then the function prevents changes from leaking into global scope. And thankfully, multiple invocations of the function do properly create multiple copies of the variable, so calling a function to generate several closures does create fully independent closures.
Here’s a somewhat practical example:
function tableRowColors(array $colors) { $i = 0; $max = count($colors); // ensure contiguous, integral keys $colors = array_values($colors); $nextColor = function () use (&$i, $max) { $color = $colors[$i]; $i = ($i + 1) % $max; return $color; }; return $nextColor; } $t1_nextColor = tableRowColors(array('#cfc', '#aea')); $t2_nextColor = tableRowColors(array('#fff', '#eee', '#ddd', '#ccc'));Now each time you call $t1_nextColor() or $t2_nextColor(), they’ll generate the next color in their respective sequence.
21 July 2008, 8:03 pmVenkman:
sapphirecat, the problem is just what is a closure.
It’s called closure because, well, it’s closed. In the examples where some function just accesses some global variable, you don’t really have a closure. The global is in scope always (naturally, that’s why it’s global).
Your second example _is_ precisely a closure. The scope is closed to the rest of the world, but it’s still referenced and available to the returned function.
So, the problem is not that “the closure leaks to the global variable”. That’s just normal behavior because it’s not a closure.
22 July 2008, 12:26 amClosures en PHP 5.3 | WEBDEV:
[...] Me quedo sorprendido al enterarme de que, probablemente, las “closures” serán implementadas en PHP 5.3. [...]
22 July 2008, 12:49 amPHP is getting closures! | Suburban Chicago PHP:
[...] I’ve seen very little from PHP that got me excited lately. So, imagine how excited I am to hear that closures are coming to PHP 5.3! [...]
22 July 2008, 6:51 amroScripts - Webmaster resources and websites:
Tower Of Power » Blog Archive » PHP 5.3 and Closures…
Tower Of Power » Blog Archive » PHP 5.3 and Closures…
22 July 2008, 10:15 amphp:
Well I’m really excited. Now I am waiting for goto() function to be implemented.. that will also be great
22 July 2008, 5:26 pm» Anonyme Funktionen in PHP 5.3 Flusensieb:
[...] hats bisher schon gegeben und zwar mittels create_function. Ab 5.3 wirds in PHP auch sogenannte Closures geben. Das Ganze schaut aus wie die anonymen Funktionen in [...]
23 July 2008, 12:50 amdahlia's me2DAY:
홍민희의 생각…
PHP 5.3 and Closures / 네임스페이스와 함께 드디어 클로져도 5.3에서 구현되는군요. Phunctional은 더이상 개발하지 않아도 될 것 같습니다….
23 July 2008, 1:41 amAnonymous (Lambda) functions in php 5.3 and above.:
[...] found a post by Daniel Cousineau on php5.3’s closures that lead me to the closures [...]
23 July 2008, 6:37 amadraðblog » Blog Archive » PHP is now less crappy than Java:
[...] And by “is less crappy than Java”, I mean “has closures”. [...]
23 July 2008, 1:44 pmMichael Kimsal:
I’m really curious if these will be ‘abused’ or ‘overused’ or ‘misused’ (by multiple different conflicting defintions!). Having used closures in Groovy where they are very central to the language, I still have a hard time seeing too many use cases in PHP right now. We’ll wait and see how the community adapts to this new aspect of the language!
23 July 2008, 2:25 pmCrystaldyn:
These are read-only closures by default. You can make them read-write by using the &-sign in the use() list, but if you’re using a global variable, you just get a normal reference to that variable. In that case, it’s not closure at all. Fortunately, it does work sanely if you define the lambda in a function or method. Then you’ll get a real, private, read-write variable. I hope that’s clear. I’m excited. I can’t use it in paid work yet, but lo! That joyous day is coming.
23 July 2008, 2:34 pmLinkdump: Matematika za programere, PHP 5.3 novosti… by Nikola Plejić:
[...] PHP 5.3 and Closures [...]
24 July 2008, 1:39 amLambda Functions in PHP | Bao's blog:
[...] : 1,2 Programming ~ Tags: closure, lambda, [...]
24 July 2008, 4:27 amBrad Miller:
Wake me when the rest of Lisp is implemented in PHP.
25 July 2008, 7:57 amdeadimp:
This is a lot better than using ‘create_function’ to make anonymous functions. Woot!
24 August 2008, 7:47 pmPHP 5.3 Improvements » EricByers.com:
[...] Lambda functions and Closures [...]
7 September 2008, 12:33 amRecent Links Tagged With "php" - JabberTags:
[...] public links >> php PHP 5.3 and Closures Saved by ckendall on Sat 27-9-2008 Using actions in your WordPress themes Saved by thedpshow on [...]
29 September 2008, 12:04 am