Menu

Collecting Interface Implementations with Signals

Subscribing to KnockoutJs ECMAScript 5 Plugin Observables

Dev Blog

From some time, PHP offers closures called also anonymous functions. The anonymous function works somewhat different than JavaScript equivalent. In JavaScript all variables are available in closure if they are defined in same scope as closure. Let's make an example in JavaScript, so that will be a bit cleaner:

// Variable $name is *outer* for $greet function
var $name = 'Joe';
var $greet = function() {
    console.log($name); // $name is `Joe` here.
}

In PHP however, these outer variables are not automatically available in function. In fact these variables are copied (with exception to objects), just like when passing variable as function argument. They need to be passed with use keyword. Equivalent in PHP:

// Variable $name is *outer* for $greet function
$name = 'Joe';
$greet = function() use ($name) {
    echo $name; // $name is `Joe` here.
}

Isolating Variables Scope

Often anonymous functions are used just to isolate scope of contained variables. That is, to create kind of private local variables. Such function is actually executed just after it was created. The plus is that it does not define any new symbols, so that it will not only prevent name collisions with other code, but itself does not add any symbol name. In JavaScript it can be defined by surrounding function with parenthesis and calling such construct. Also optional parameters can be provided, for instance window to pass variables to outer scope:

(
    function(window, name){
        console.log('Hello ' + name);
        window.test = 'foo';
    }
)(window, 'Joe');
console.log(window.test);

After executing such function, window object will have new test property, and the code inside function body will be executed. Without polluting symbol namespace.

PHP offers anonymous function too, and it turned out that those functions can also be executed without assigning them to any variable. The syntax is actually the same as in JavaScript:

<?php
$window = new stdClass;
(function($window, $test){
    echo 'Hello ' . $test . PHP_EOL;
    $window->test = 'foo';
})($window, 'Joe');
echo $window->test . PHP_EOL;

Use Case

There might be some use cases for such construct especially in application bootstrap files or autoloaded file, which will handle something. In example below, the anonymous function is used to define class aliases. This allows including such file anywhere in application without concerns of overwriting existing variables: 

<?php
(function(){
    $classes = [
        'Maslosoft\\Widgets\\Breadcrumbs' => 'Breadcrumbs',
        'Maslosoft\\Widgets\\Html\\Decorator' => 'Decorator',
        'Maslosoft\\Widgets\\Search\\SearchDrawer' => 'SearchDrawer',
    ];
    foreach ($classes as $fullName => $shortName) {
        class_alias($fullName, $shortName);
    }
})();

Such file can be included in composer.json file autoload section, so that all class aliases will be available in application, whether dependency containing this snippet will be installed:

{
  "autoload": {
    "psr-4":{
      "files": [
        "src/Aliases.php"
      ]
    }
  }
}

Have a nice day!