Test HTTP Requests Tools Blog Learn Quizzes Smile API Log In / Sign Up
Test HTTP Requests Tools Blog Learn Quizzes Smile API Log In / Sign Up
« Return to the tutorials listFeatured in PHP Weekly
We have updated the website and our policies to make sure your privacy rights and security are respected.
Click here to learn more about the way our website handles your data.

Remove this message.

Basic usage of closures in PHP

Difficulty: 30 / 50 Tweet
php-closures

Closures have been introduced in PHP 5.3 and their most important use is for callback functions. Basically a closure in PHP is a function that can be created without a specified name - an anonymous function. Here's a closure function created as the second parameter of array_walk(). By specifying the $v parameter as a reference one can modify each value in the original array through the closure function.

  
    <?php
      $array = array('Ruby', 'PHP', 'JavaScript', 'HTML');
      array_walk($array, function(&$v, $k) {
        $v = $v . ' - Programming Language';
      });
      print_r($array);
  

Assigning a closure as the value of a variable

You can define a closure as the value of a variable with a normal assignment. For example, the snippet below will print out 'I am a closure'.

  
    <?php
    $var = function() {
      return 'I am a ' . func_get_arg(0);
    };
    print_r($var('Closure'));
  

Don't forget to end the assignment with a semicolon just like you would do with any variable definition ... I always forget so I thought it would help if I mentioned this :).

Be careful with the scope

One of the most confusing aspects for these anonymous functions in PHP is related to how closures can make use of variables from their immediate parent scope (not necessarily the global scope). This is done with the use language construct so that the syntax looks like this: function() use ($variable) { /* code */ }.

In the example below, the closure will use / inherit the value of $param from its parent scope which is the scope of the sayHello() function, NOT the global scope and therefor the script will output Hi, I am Michael!.

  
    <?php
    $param  = 'John!';

    function sayHello()
    {
      $param = 'Michael!';
      $func  = function() use ($param)
      {
        echo 'Hi, I am ' . $param;
      };
      $func();
    }

    sayHello();
  

If we were to modify the value of $param inside the closure this would not affect it's value inside the parent scope unless we would 'use a reference'. In the two examples below, one with $param as a reference and one as a normal (copied) variable the results are different.

This prints 'I am Michael!' because $param is not modified in its parent scope. In other words, the only place where $param='Dave!' is inside the closure.

  
    <?php
    $param  = 'John!';

    function sayHello()
    {
      $param = 'Michael!';
      $func  = function() use ($param)
      {
        $param = 'Dave!';
      };
      $func();
      echo 'I am ' . $param; // prints I am Michael!
    }
    sayHello();
  

The code below will print 'I am Dave!' because $param is 'used' as a reference.

  
    <?php
    $param  = 'John!';

    function sayHello()
    {
      $param = 'Michael!';
      $func  = function() use (&$param)
      {
        $param = 'Dave!';
      };
      $func();
      echo 'I am ' . $param; // prints I am Dave!
    }
    sayHello();
  
comments powered by Disqus