Closures - PHP vs Javascript
Tags: php, javascript
Published: 2020-01-28 09:42:35

---
title: Closures - PHP vs Javascript
published: true
tags: php,javascript
canonical_url: https://codeinphp.github.io/post/closures-php-vs-javascript/
---

In my previous post [Exploring Lambda Functions and Closures in PHP](http://codeinphp.github.io/post/exploring-lambda-functions-and-closures-in-php/), I gave you example of function that can calculate factorial of given number:

```
$factorial = function( $n ) use ( &$factorial ) {
    if( $n == 1 ) return 1;
    return $factorial( $n - 1 ) * $n;
};

echo $factorial( 5 ); // 120
```

In that post I simply said it is important to pass `$factorial` by **reference** otherwise it won't work. Let's explore why it is so in this post.

Closures are pretty common in Javascript so let's create a simple closure in it and see how it behaves:

```
var addOne = function(num) {
    return function() { 
        console.log(num++); 
    };
};

var f = addOne(1);

f(); // 1
f(); // 2
f(); // 3
```

As can be seen, each time we call the function, it increments the number. Let's now convert the same in PHP:

```
$addOne = function($num) {
    return function() { 
        echo $num++; 
    };
};

$f = $addOne(1);

$f();
$f();
$f();
```

This would result in error:

`Notice: Undefined variable: num`

Why is it so ? Because variable scope is different in PHP and Javascript. In PHP, all variables go in local scope by default unless you explicitly declare them in global scope. However in Javascript all variables go in global scope unless you explicitly declare them in local scope using `var` keyword. Since we are talking about functions and closures here, we can say that in PHP _a variable declared in a function can only be available to that function_ where it is declared. On the other hand, in Javascript _a variable can not only be available to function where it is declared but also to inner functions of that parent function_. Let's see an example:

```
function test() {
  $variable = 'value';

  return function() {
    echo $variable;
  };
}

$f = test();
$f(); // Notice: Undefined variable: variable
```

So PHP gave error as inner function didn't had access to outer variable `$variable`. We could have made this variable available to inner function either by creating closure using `use` keyword or declaring that variable in global scope. Le't see same example in Javascript:

```
function test() {
  var variable = 'value';

  return function() {
    console.log(variable);
  };
}

var f = test();
f(); // value
```

In Javascript though, the inner function was able to get variable from outer scope eg parent function in this example.

This is reason why Javascript inner function shown above didn't give error whereas PHP's did. Therefore to have access to outer variable in PHP, we need to create a closure by using the `use` keyword. Of course in Javascript, you don't need something like `use` keyword because as I mentioned in Javascript a variable of a parent function is available to all its inner functions as well. So we need to use the `use` keyword in PHP due to difference of variable scoping in PHP and Javascript.

So let's fix that error we received earlier in PHP:

```
$addOne = function($num) {
    return function() use ($num) { 
        echo $num++; 
    };
};

$f = $addOne(1);

$f(); // 1
$f(); // 1
$f(); // 1
```

Now we have created the closure and error is gone and `$num` variable is now available to inner function but there is a problem, each time we call the function it says `1` unlike Javascript example we saw earlier which said `1`, `2` and `3`. That's because unlike Javascript, PHP creates a new local variable inside inner function eg passes it by `value` not by `reference`. Conceptually, PHP sees this code like this:

```
$addOne = function($num) {
    return function() use ($num) { 
        $num = 1; // so PHP kind of creates a new variable and assigns to 1 each time you call this
        echo $num++; 
    };
};
```

So to get similar output as in Javascript, we need to pass the variable using `reference` which can be done by using the `&` symbol:

```
$addOne = function($num) {
    return function() use (&$num) { // passed by reference 
        echo $num++; 
    };
};

$f = $addOne(1);

$f();
$f();
$f();
```

and now we get the output `1`, `2`, and `3`.

* * *

And that's also reason why you needed to pass variable by `reference` for the factorial example I had given in my [previous post](http://codeinphp.github.io/post/exploring-lambda-functions-and-closures-in-php/). Hope this post clears the confusion of closures and scoping especially for someone who comes from Javascript to PHP.

 ![](http://feeds.feedburner.com/~r/codeinphpfeed/~4/xA7G0kbIW-A)