Javascript closures vs PHP closures, what’s the difference?

One difference is how both cope with storing the context in which an anonymous function is executed:

// JavaScript:
var a = 1;
var f = function() {
   console.log(a);
};
a = 2;
f();
// will echo 2;

// PHP
$a = 1;
$f = function() {
    echo $a;
};
$a = 2;
$f();
// will result in a "PHP Notice:  Undefined variable: a in Untitled.php on line 5"

To fix this notice you’ll have to use the use syntax:

$a = 1;
$f = function() use ($a) {
    echo $a;
};
$a = 2;
$f();
// but this will echo 1 instead of 2 (like JavaScript)

To have the anonymous function behave somehow like the JavaScript counterpart you’ll have to use references:

$a = 1;
$f = function() use (&$a) {
    echo $a;
};
$a = 2;
$f();
// will echo 2

I think this is the most striking difference between JavaScript and PHP closures.

Second difference is that every JavaScript closure has a this context available which means, that you can use this inside the closure itself (although it’s often quite complicated to figure out what this actually refers to) – PHP’s current stable version (PHP 5.3) does not yet support $this inside a closure, but PHP’s upcoming version (PHP 5.4) will support $this binding and rebinding using $closure->bind($this) (See the Object Extension RFC for more info.)

Third difference is how both languages treat closures assigned to object properties:

// JavaScript
var a = {
    b: function() {}
};
a.b(); // works


// PHP
$a = new stdClass();
$a->b = function() {};
$a->b(); // does not work "PHP Fatal error:  Call to undefined method stdClass::b() in Untitled.php on line 4"

$f = $a->b;
$f(); // works though

The same is true if closures are assigned to properties in class definitions:

class A {
    public $b;

    public function __construct() {
        $this->b = function() {};
    }

    public function c() {
        $this->b();
    }
}
$a = new A();
// neither
$a->b();
// nor
$a->c();
// do work

Fourth difference: JavaScript Closures are full fledged objects, wheres in PHP they are restricted objects. For instance, PHP Closures cannot have properties of their own:

$fn = function() {};
$fn->foo = 1;
// -> Catchable fatal error: Closure object cannot have properties

while in JavaScript you can do:

var fn = function() {};
fn.foo = 1;
fn.foo; // 1

Fifth difference: Returned closures can be immediately called upon in Javascript:

var fn = function() { return function() { alert('Hi');}}
fn()();    

Not in PHP:

$fn = function() { return function() { echo('Hi');};};
$fn()();     // syntax error

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)