The Server Pages
:: TSP Menu
- Home
- Authors
- Glossary
- RSS Feed

:: Servers
- CPanel
- Hosting
- Linux
- Windows

:: Webmaster
- Databases
- Design
- PHP
- Search Engines

:: Scripts
- Scripts

:: Documentation
- PHP Manual

:: Other
- Errors & Solutions
- TechPunt
- Wojjie

search for in the

Classes and Objects> <Internal (built-in) functions
[edit] Last updated: Sat, 12 May 2012

view this page in

Anonymous functions

Anonymous functions, also known as closures, allow the creation of functions which have no specified name. They are most useful as the value of callback parameters, but they have many other uses.

Example #1 Anonymous function example

<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
    return 
strtoupper($match[1]);
}, 
'hello-world');
// outputs helloWorld
?>

Closures can also be used as the values of variables; PHP automatically converts such expressions into instances of the Closure internal class. Assigning a closure to a variable uses the same syntax as any other assignment, including the trailing semicolon:

Example #2 Anonymous function variable assignment example

<?php
$greet 
= function($name)
{
    
printf("Hello %s\r\n"$name);
};

$greet('World');
$greet('PHP');
?>

Closures may also inherit variables from the parent scope. Any such variables must be declared in the function header. Inheriting variables from the parent scope is not the same as using global variables. Global variables exist in the global scope, which is the same no matter what function is executing. The parent scope of a closure is the function in which the closure was declared (not necessarily the function it was called from). See the following example:

Example #3 Closures and scoping

<?php
// A basic shopping cart which contains a list of added products
// and the quantity of each product. Includes a method which
// calculates the total price of the items in the cart using a
// closure as a callback.
class Cart
{
    const 
PRICE_BUTTER  1.00;
    const 
PRICE_MILK    3.00;
    const 
PRICE_EGGS    6.95;

    protected 
$products = array();
    
    public function 
add($product$quantity)
    {
        
$this->products[$product] = $quantity;
    }
    
    public function 
getQuantity($product)
    {
        return isset(
$this->products[$product]) ? $this->products[$product] :
               
FALSE;
    }
    
    public function 
getTotal($tax)
    {
        
$total 0.00;
        
        
$callback =
            function (
$quantity$product) use ($tax, &$total)
            {
                
$pricePerItem constant(__CLASS__ "::PRICE_" .
                    
strtoupper($product));
                
$total += ($pricePerItem $quantity) * ($tax 1.0);
            };
        
        
array_walk($this->products$callback);
        return 
round($total2);
    }
}

$my_cart = new Cart;

// Add some items to the cart
$my_cart->add('butter'1);
$my_cart->add('milk'3);
$my_cart->add('eggs'6);

// Print the total with a 5% sales tax.
print $my_cart->getTotal(0.05) . "\n";
// The result is 54.29
?>

Anonymous functions are implemented using the Closure class.

Changelog

Version Description
5.4.0 $this can be used in anonymous functions.
5.3.0 Anonymous functions become available.

Notes

Note: It is possible to use func_num_args(), func_get_arg(), and func_get_args() from within a closure.



Classes and Objects> <Internal (built-in) functions
[edit] Last updated: Sat, 12 May 2012
 
add a note add a note User Contributed Notes Anonymous functions
orwellophile at phpblue dot net 15-Mar-2012 11:42
You can create a dynamic method with a class, with access to member variables, with a little bit of trickery:

<?
   
class DynamicFunction {
        var
$functionPointer;
        var
$mv = "The Member Variable";

        function
__construct() {
           
$this->functionPointer = function($arg) {
                return
sprintf("I am the default closure, argument is %s\n", $arg);
            };
        }

        function
changeFunction($functionSource) {
           
$functionSource = str_replace('$this', '$_this', $functionSource);
           
$_this = clone $this;

           
$f = '$this->functionPointer = function($arg) use ($_this) {' . PHP_EOL;
           
$f.= $functionSource . PHP_EOL . "};";
            eval(
$f);
        }

        function
__call($method, $args) {
            if (
$this->{$method} instanceof Closure ) {
                return
call_user_func_array($this->{$method},$args);
            } else {
                throw new
Exception("Invalid Function");
            }
        }
    }

    if (!empty(
$argc) && !strcmp(basename($argv[0]), basename(__FILE__))) {
       
$dfstring1 = 'return sprintf("I am dynamic function 1, argument is %s, member variables is %s\n", $arg, $this->mv);';
       
$dfstring2 = 'return sprintf("I am dynamic function 2, argument is %s, member variables is %s\n", $arg, $this->mv);';

       
$df = new DynamicFunction();
       
$df->changeFunction($dfstring1);
        echo
$df->functionPointer("Rabbit");

       
$df->changeFunction($dfstring2);
       
$df->mv = "A different var";
        echo
$df->functionPointer("Cow");
    };
?>
mike at borft dot student dot utwente dot nl 24-Jan-2012 08:46
Since it is possible to assign closures to class variables, it is a shame it is not possible to call them directly. ie. the following does not work:
<?php
class foo {

  public
test;

  public function
__construct(){
   
$this->test = function($a) {
      print
"$a\n";
    };
  }
}

$f = new foo();

$f->test();
?>

However, it is possible using the magic __call function:
<?php
class foo {

  public
test;

  public function
__construct(){
   
$this->test = function($a) {
      print
"$a\n";
    };
  }

  public function
__call($method, $args){
    if (
$this->{$method} instanceof Closure ) {
      return
call_user_func_array($this->{$method},$args);
    } else {
      return
parent::__call($method, $args);
    }
  }
}
$f = new foo();
$f->test();
?>
it
Hope it helps someone ;)
lennymail at nospam dot gmail dot com 05-Oct-2011 05:40
A practical example of anonymous functions could be a clean template system. Here you can completely remove messy HTML from your code and keep everything very readable. The last statement that prints the HTML in the example below resembles LISP or other functional type languages. The closure retains the HTML tag from parent scope(which can be initialized in creative ways) and properly closes it after the function call. Items can either nested or composed within HTML tags.

You can take this idea further and "map and wrap" columns and rows of recordsets with HTML for display. All that is missing now is the CSS to make it attractive in the browser.

Closures can be thought of as a very primitive class that has one "apply" method with some private and public data. Functional programming has been around since the first programming languages in the 1950s.

<?php

function html ($code , $id="", $class=""){
    if (
$id !== "") $id = " id = \"$id\"" ;
   
$class =  ($class !== "")? " class =\"$class\"":">";
   
$open = "<$code$id$class";
   
$close = "</$code>";
    return function (
$inner = "") use ($open, $close){
        return
"$open$inner$close";};

}
$layout = array('container','header','pmain','lsidebar','rsidebar','footer');

foreach (
$layout as $element)
   $
$element = html ("div", $element);

$div = html("div", "test");

$bold = html('strong');
$italic = html('i');

$msg= $div($bold($italic("hello from the left sidebar")));

echo
$container(
   
$header(
       
"This is the header").$pmain(
           
$lsidebar(
               
$msg).$rsidebar(
               
"This is the right sidebar")).$footer(
    ));
hernan_javier_saab at yahoo dot com 23-Sep-2011 04:54
When invoking an anonymous function through throughThroughFunction(), all variables are automatically binded to the inner function. In addition, variables created within the anonymous function are also "binded out" incorporating it to the scope where the anonymous function is being created.
Enjoy!

<?php
class ThroughThrogh {
    public
$to_export = array();
    public
$to_import = array();
   
   
// we eval() these functions in order to cleanup verbosity. Cleaner this way even though we all heard about the nightmares of eval()
   
const TX_START_X = 'foreach(get_defined_vars() as $k=>$v){$this->to_export[$k] =&${$k};};';
    const
TX_START_I = 'foreach($that->to_export as $name => &$variable) ${$name} = &$variable;';
    const
TX_END_X = 'foreach(get_defined_vars() as $k=>$v){if(!isset($that->to_export[$k])) $that->to_import[$k] =&${$k};};';
    const
TX_END_I = 'foreach($this->to_import as $name => &$variable) ${$name} = &$variable;';

    public function
hackClosure($closure, $inject_start, $inject_end) {
       
$reflection = new ReflectionFunction($closure);
       
$tmp = $reflection->getParameters();
       
$args = array('$that');
        foreach (
$tmp as $a)
           
array_push($args, '$' . $a->getName() . ($a->isDefaultValueAvailable() ? '=\'' . $a->getDefaultValue() . '\'' : ''));
       
$file = new SplFileObject($reflection->getFileName());
       
$file->seek($reflection->getStartLine() - 1);
       
$code = '';
        while (
$file->key() < $reflection->getEndLine()) {
           
$code .= $file->current();
           
$file->next();
        }
       
$start = strpos($code, '{') + 1;
       
$end = strrpos($code, '}');
        return
create_function(implode(', ', $args), "$inject_start;" substr($code, $start, $end - $start) . "$inject_end;");
    }
 
   
   
//here is where we invoke the function
   
public function throughThroughFunction($that, $callback){
       
$this->to_export["that"] = $that;
       
       
$inject_start = self::TX_START_I;// potentially you can add setup code in here
       
$inject_end = self::TX_END_X;// potentially you can add cleanup code in here
       
$callback = $this->hackClosure($callback, $inject_start, $inject_end);
       
       
call_user_func($callback, $that);
    }
   
   
//user test
   
public function test(){

      
$outscope = "Source External Scope: test... not modified if seen at end of function\n";
      
$this->test = "Source External Scope: object attribute from outside anonymous function\n";
       eval(
$this::TX_START_X); //required to export all variables from scope
      
$this->throughThroughFunction($this, function(){
          
           echo
"Source Anonymous Function\n";
           echo
$outscope;
           echo
$that->test;
          
$that->test = "Source Anonymous Function Scope: wow! Object attribute modified from inside anonymous function\n";
          
$outscope = "Source Anonymous Function Scope: yey! Variable Modified from the scope of an anonymous function!\n";
          
$from_anonymous_function = "Source Anonymous Function Scope: No way! How did you do that?\n";
           
           
           
        } );
        eval(
$this::TX_END_I); //require to bring newly created variables from anonymous function into current scope
       
echo "\nSource External Scope\n";
        echo
$from_anonymous_function;
        echo
$outscope;
        echo
$this->test;
    }

}

$demo = new ThroughThrogh();
$demo->test();
?>

Output
 
Source Anonymous Function
Source External Scope: test... not modified if seen at end of function
Source External Scope: object attribute from outside anonymous function

Source External Scope
Source Anonymous Function Scope: No way! How did you do that?
Source Anonymous Function Scope: yey! Variable Modified from the scope of an anonymous function!
Source Anonymous Function Scope: wow! Object attribute modified from inside anonymous function
reinaldorock at yahoo dot com dot br 27-Aug-2011 03:15
Using closure to encapsulate environment
<?php
    $fib
= function($n) use(&$fib) {
        if(
$n == 0 || $n == 1) return 1;
        return
$fib($n - 1) + $fib($n - 2);
    };

   echo
$fib(2) . "\n"; // 2
  
$lie = $fib;
  
$fib = function(){die('error');};//rewrite $fib variable
  
echo $lie(5); // error   because $fib is referenced by closure

?>

Alternative Fibonacci implementation using a self called function like javascript to encapsulate references variables.

<?php
$fib
= call_user_func(function(){
  
   
$fib = function($n) use(&$fib) {
        if(
$n == 0 || $n == 1) return 1;
        return
$fib($n - 1) + $fib($n - 2);
    };

    return
$fib;
});

echo
$fib(2) . "\n";//2
$ok = $fib;

$fib = function(){die('error')};//rewrite $fib variable but don't referenced $fib used by closure
echo $ok(5);//result ok
?>
ldrut 13-Aug-2011 08:24
A common way to avoid contaminating Javascript global space with unneeded variables is to move the code into an immediately called anonymous closure.

(function(){ ... })()

The equivalent way to do that in PHP 5.3+ is

call_user_func(function() use(closure-vars){ ... });
simon at generalflows dot com 05-Aug-2011 03:23
<?php

/*
 * An example showing how to use closures to implement a Python-like decorator
 * pattern.
 *
 * My goal was that you should be able to decorate a function with any
 * other function, then call the decorated function directly:
 *
 * Define function:         $foo = function($a, $b, $c, ...) {...}
 * Define decorator:        $decorator = function($func) {...}
 * Decorate it:             $foo = $decorator($foo)
 * Call it:                 $foo($a, $b, $c, ...)
 *
 * This example show an authentication decorator for a service, using a simple
 * mock session and mock service.
 */
 
session_start();

/*
 * Define an example decorator. A decorator function should take the form:
 * $decorator = function($func) {
 *     return function() use $func) {
 *         // Do something, then call the decorated function when needed:
 *         $args = func_get_args($func);
 *         call_user_func_array($func, $args);
 *         // Do something else.
 *     };
 * };
 */
$authorise = function($func) {
    return function() use (
$func) {
        if (
$_SESSION['is_authorised'] == true) {
           
$args = func_get_args($func);
           
call_user_func_array($func, $args);
        }
        else {
            echo
"Access Denied";
        }
    };
};

/*
 * Define a function to be decorated, in this example a mock service that
 * need to be authorised.
 */
$service = function($foo) {
    echo
"Service returns: $foo";
};

/*
 * Decorate it. Ensure you replace the origin function reference with the
 * decorated function; ie just $authorise($service) won't work, so do
 * $service = $authorise($service)
 */
$service = $authorise($service);

/*
 * Establish mock authorisation, call the service; should get
 * 'Service returns: test 1'.
 */
$_SESSION['is_authorised'] = true;
$service('test 1');

/*
 * Remove mock authorisation, call the service; should get 'Access Denied'.
 */
$_SESSION['is_authorised'] = false;
$service('test 2');

?>
paul at somewhere dot com 06-Mar-2011 08:36
I benched instantiating a function and lambda function.

Functions used:
<?php

function data() {
 
$var = 'hi';
}
$lambda = function() {
 
$var = 'hi';
}

?>

Bench for instantiating a function:
1.692800000000000082422957 μs
Bench for instantiating Lambda Function:
0.906000000000000027533531 μs
Bench for calling function:
0.7153000000000000468958206 μs
Bench for calling lambda function:
0.6914000000000000145661261 μs

Calling the lambda function and regular function fluctuates between .81 and .65 so they seem to be the same.
fabiolimasouto at gmail dot com 24-Feb-2011 01:51
You may have been disapointed if you tried to call a closure stored in an instance variable as you would regularly do with methods:

<?php

$obj
= new StdClass();

$obj->func = function(){
 echo
"hello";
};

//$obj->func(); // doesn't work! php tries to match an instance method called "func" that is not defined in the original class' signature

// you have to do this instead:
$func = $obj->func;
$func();

// or:
call_user_func($obj->func);

// however, you might wanna check this out:
$array['func'] = function(){
 echo
"hello";
};

$array['func'](); // it works! i discovered that just recently ;)
?>

Now, coming back to the problem of assigning functions/methods "on the fly" to an object and being able to call them as if they were regular methods, you could trick php with this lawbreaker-code:

<?php
class test{
 private
$functions = array();
 private
$vars = array();
 
 function
__set($name,$data)
 {
  if(
is_callable($data))
   
$this->functions[$name] = $data;
  else
  
$this->vars[$name] = $data;
 }
 
 function
__get($name)
 {
  if(isset(
$this->vars[$name]))
   return
$this->vars[$name];
 }
 
 function
__call($method,$args)
 {
  if(isset(
$this->functions[$method]))
  {
  
call_user_func_array($this->functions[$method],$args);
  } else {
  
// error out
 
}
 }
}

// LET'S BREAK SOME LAW NOW!
$obj = new test;

$obj->sayHelloWithMyName = function($name){
 echo
"Hello $name!";
};

$obj->sayHelloWithMyName('Fabio'); // Hello Fabio!

// THE OLD WAY (NON-CLOSURE) ALSO WORKS:

function sayHello()
{
 echo
"Hello!";
}

$obj->justSayHello = 'sayHello';
$obj->justSayHello(); // Hello!
?>

NOTICE: of course this is very bad practice since you cannot refere to protected or private fields/methods inside these pseudo "methods" as they are not instance methods at all but rather ordinary functions/closures assigned to the object's instance variables "on the fly". But I hope you've enjoyed the jurney ;)
Suman Madavapeddi. 14-Feb-2011 11:31
These  Closures are really interesting to me .This would be helpful.
<?php
Class Operations{
    public function
ops($x,$y,$op){
        switch (
$op){
            case
'ADD':return function() use($x,$y){
                            return
$x+$y."<br>";                           
                       };
                       break;
            case
'SUB': return function() use ($x,$y){
                            return
$x-$y."<br>";                           
                        };
                        break;
            default:    return function(){
                            return
"Operation is not supported by class"."<br>";
                        };
        }           
    }
}

$op =  new Operations();
$fn1 = $op->ops(6,7,'ADD');
echo
$fn1();

$fn2 = $op->ops(6,2,'SUB');
echo
$fn2();

$fn2 = $op->ops(6,7,'MUL');
echo
$fn2();
?>
Anonymous 27-Oct-2010 07:54
use() parameters are early binding - they use the variable's value at the point where the lambda function is declared, rather than the point where the lambda function is called (late binding).

If you want late binding put & before the variable inside use()
<?php
$fn
= function () use (&$var) { echo $var; };
?>
Examples:
<?php
// problem 1: this should echo "Canada", not a php notice
$fn = function () use ($country) { echo $country . "\n"; };
$country = 'Canada';
$fn();

// problem 2: this should echo "Canada", not "UnitedStates"
$country = 'UnitedStates';
$fn = function () use ($country) { echo $country . "\n"; };
$country = 'Canada';
$fn();

// problem 3: this should echo "Canada", not "UnitedStates"
$country = (object)array('name' => 'UnitedStates');
$fn = function () use ($country) { echo $country->name . "\n"; };
$country = (object)array('name' => 'Canada');
$fn();

// problem 4: this outputs "Canada". if this outputs "Canada",
// then so should problem 2 above. otherwise this should be
// just as broken as problem 2 and be outputting "UnitedStates"
$country = (object)array('name' => 'UnitedStates');
$fn = function () use ($country) { echo $country->name . "\n"; };
$country->name = 'Canada';
$fn();
?>
see http://bugs.php.net/bug.php?id=50980
(I've just quoted from there, but if you want you can read there the whole feature request)
Hayley Watson 22-Oct-2010 02:00
As an alternative to gabriel's recursive construction, you may instead assign the recursive function to a variable, and use it by reference, thus:

<?php
$fib
= function($n)use(&$fib)
{
    if(
$n == 0 || $n == 1) return 1;
    return
$fib($n - 1) + $fib($n - 2);
};

echo
$fib(10);
?>
Hardly a sensible implementation of the Fibonacci sequence, but that's not the point! The point is that the variable needs to be used by reference, not value.

Without the '&', the anonymous function gets the value of $fib at the time the function is being created. But until the function has been created, $fib can't have it as a value! It's not until AFTER the function has been assigned to $fib that $fib can be used to call the function - but by then it's too late to pass its value to the function being created!

Using a reference resolves the dilemma: when called, the anonymous function will use $fib's current value, which will be the anonymous function itself.

At least, it will be if you don't reassign $fib to anything else between creating the function and calling it:

<?php
$fib
= function($n)use(&$fib)
{
    if(
$n == 0 || $n == 1) return 1;
    return
$fib($n - 1) + $fib($n - 2);
};

$lie = $fib;

$fib = function($n)
{
    return
100;
};

echo
$lie(10); // 200, because $fib(10 - 1) and $fib(10 - 2) both return 100.
?>

Of course, that's true of any variable: if you don't want its value to change, don't change its value.

All the usual scoping rules for variables still apply: a local variable in a function is a different variable from another one with the same name in another function:

<?php
$fib
= function($n)use(&$fib)
{
    if(
$n == 0 || $n == 1) return 1;
    return
$fib($n - 1) + $fib($n - 2);
};

$bark = function($f)
{
   
$fib = 'cake';    // A totally different variable from the $fib above.
   
return 2 * $f(5);
};

echo
$bark($fib); // 16, twice the fifth Fibonacci number

?>
anonymous 18-Aug-2010 10:21
Base dao class illustrating the usefulness of closures.
* Handles opening and closing of connections.
* Adds slashes sql
* Type checking of sql parameters and casts as appropriate
* Provides hook for processing of result set and emitting one or more objects.
* Provides hook for accessing underlying link and result objects.

<?php

define
("userName","root");
define("password","root");
define("dbName","ahcdb");
define("hostName","localhost");

class
BaseDao {

    function
getConnection()    {
       
$link = mysql_connect(hostName, userName, password);
        if (!
$link)
            die(
"Could not connect: " . mysql_error());
        if (!
mysql_select_db(dbName))
            die(
"Could not select database: " . mysql_error());
        return
$link;
    }
   
    function
setParams(& $sql, $params)    {
        if(
$params != null)
           
$sql = vsprintf($sql, array_map(function($n) {
                if(
is_int($n))
                    return (int)
$n;
                if(
is_float($n))
                    return (float)
$n;
                if(
is_string($n))
                    return
"'".mysql_real_escape_string($n)."'";
                return
mysql_real_escape_string($n);
            },
$params));
    }

    function
executeQuery($sql, $params, $callback = null)    {
       
$link  = $this->getConnection();
       
$this->setParams($sql, $params);
       
$return = null;
        if((
$result = mysql_query($sql, $link)) != null)
            if(
$callback != null)
               
$return = $callback($result, $link);
        if(
$link != null)
           
mysql_close($link);
        if(!
$result)
            die(
"Fatal Error: Invalid query '$sql' : " . mysql_error());
        return
$return;
    }
 
    function
getList($sql, $params, $callback)    {
        return
$this->executeQuery($sql, $params, function($result, $link) use ($callback) {
           
$idx = 0;
           
$list = array();
            while (
$row = mysql_fetch_assoc($result))
                if(
$callback != null)
                   
$list[$idx] = $callback($idx++, $row);
            return
$list;
        });
    }
   
    function
getSingle($sql, $params, $callback)    {
        return
$this->executeQuery($sql, $params, function($result, $link) use ($callback) {
            if (
$row = mysql_fetch_assoc($result))
               
$obj = $callback($row);
            return
$obj;
        });
    }
}

class
Example    {
    var
$id;
    var
$name;
   
    function
Example($id, $name){
       
$this->id = $id;
       
$this->name = $name;
    }
   
    function
setId($id){
       
$this->id = $id;
    }
}

class
ExampleDao extends BaseDao    {
   
   
    function
getAll(){
        return
parent::getList("select * from nodes", null, function($idx, $row) {
            return new
Example($row["id"], $row["name"]);
        });
    }
   
    function
load($id){
        return
parent::getSingle("select * from nodes where id = %1\$s", array($id), function($row) {
            return new
Example($row["id"], $row["name"]);
        });
    }
   
    function
update($example){
        return
parent::executeQuery("update nodes set name = '' where  id = -1", null, function($result, $link){
            return
$result;
        });
    }
   
    function
insert(& $example){
        return
parent::executeQuery("insert into nodes", null, function($result, $link) use ($example){
           
$id = mysql_insert_id($link);
           
$example->setId($id);
            return
$result;
        });
    }   
}

$exampleDao = new ExampleDao();

$list = $exampleDao->getAll());

$exampleObject = $exampleDao->load(1));

$exampleDao->update($exampleObject);

?>
orls 08-Aug-2010 01:53
Watch out when 'importing' variables to a closure's scope  -- it's easy to miss / forget that they are actually being *copied* into the closure's scope, rather than just being made available.

So you will need to explicitly pass them in by reference if your closure cares about their contents over time:

<?php
$result
= 0;

$one = function()
{
var_dump($result); };

$two = function() use ($result)
{
var_dump($result); };

$three = function() use (&$result)
{
var_dump($result); };

$result++;

$one();    // outputs NULL: $result is not in scope
$two();    // outputs int(0): $result was copied
$three();    // outputs int(1)
?>

Another less trivial example with objects (what I actually tripped up on):

<?php
//set up variable in advance
$myInstance = null;

$broken = function() uses ($myInstance)
{
    if(!empty(
$myInstance)) $myInstance->doSomething();
};

$working = function() uses (&$myInstance)
{
    if(!empty(
$myInstance)) $myInstance->doSomething();
}

//$myInstance might be instantiated, might not be
if(SomeBusinessLogic::worked() == true)
{
   
$myInstance = new myClass();
}

$broken();    // will never do anything: $myInstance will ALWAYS be null inside this closure.
$working();    // will call doSomething if $myInstance is instantiated

?>
gabriel dot totoliciu at ddsec dot net 19-Jul-2010 05:56
If you want to make a recursive closure, you will need to write this:

$some_var1="1";
$some_var2="2";

function($param1, $param2) use ($some_var1, $some_var2)
{

//some code here

call_user_func(__FUNCTION__, $other_param1, $other_param2);

//some code here

}

If you need to pass values by reference you should check out

http://www.php.net/manual/en/function.call-user-func.php
http://www.php.net/manual/en/function.call-user-func-array.php

If you're wondering if $some_var1 and $some_var2 are still visible by using the call_user_func, yes, they are available.
martin dot partel at gmail dot com 11-Jun-2010 05:50
$this is currently (PHP 5.3.2) not usable directly with closures.

One can write:
<?php
$self
= $this;
function () use (
$self) { ... }
?>
but then the private/protected members of $this cannot be used inside the closure. This makes closures much less useful in OO code.

Until this is fixed, one can cheat using reflection:
<?php
class FullAccessWrapper
{
    protected
$_self;
    protected
$_refl;
   
    public function
__construct($self)
    {
       
$this->_self = $self;
       
$this->_refl = new ReflectionObject($self);
    }
   
    public function
__call($method, $args)
    {
       
$mrefl = $this->_refl->getMethod($method);
       
$mrefl->setAccessible(true);
        return
$mrefl->invokeArgs($this->_self, $args);
    }
   
    public function
__set($name, $value)
    {
       
$prefl = $this->_refl->getProperty($name);
       
$prefl->setAccessible(true);
       
$prefl->setValue($this->_self, $value);
    }
   
    public function
__get($name)
    {
       
$prefl = $this->_refl->getProperty($name);
       
$prefl->setAccessible(true);
        return
$prefl->getValue($this->_self);
    }
   
    public function
__isset($name)
    {
       
$value = $this->__get($name);
        return isset(
$value);
    }
}

/**
 * Usage:
 * $self = giveAccess($this);
 * function() use ($self) { $self->privateMember... }
 */
function giveAccess($obj)
{
    return new
FullAccessWrapper($obj);
}

// Example:

class Foo
{
    private
$x = 3;
    private function
f()
    {
        return
15;
    }
   
    public function
getClosureUsingPrivates()
    {
       
$self = giveAccess($this);
        return function () use (
$self) {
            return
$self->x * $self->f();
        };
    }
}

$foo = new Foo();
$closure = $foo->getClosureUsingPrivates();
echo
$closure() . "\n"; // Prints 45 as expected
?>
kdelux at gmail dot com 14-May-2010 03:55
Here is an example of one way to define, then use the variable ( $this ) in Closure functions.  The code below explores all uses, and shows restrictions.

The most useful tool in this snippet is the requesting_class() function that will tell you which class is responsible for executing the current Closure(). 

Overview:
-----------------------
Successfully find calling object reference.
Successfully call $this(__invoke);
Successfully reference $$this->name;
Successfully call call_user_func(array($this, 'method'))

Failure: reference anything through $this->
Failure: $this->name = '';
Failure: $this->delfect();

<?php
 
   
   
   
function requesting_class()
    {
        foreach(
debug_backtrace(true) as $stack){
            if(isset(
$stack['object'])){
                return
$stack['object'];
            }
        }
       
    }
   
       
   
   
   
   
    class
Person
   
{
        public
$name = '';
        public
$head = true;
        public
$feet = true;
        public
$deflected = false;
       
        function
__invoke($p){ return $this->$p; }
        function
__toString(){ return 'this'; } // test for reference
       
       
function __construct($name){ $this->name = $name; }
        function
deflect(){ $this->deflected = true; }
       
        public function
shoot()
        {
// If customAttack is defined, use that as the shoot resut.  Otherwise shoot feet
           
if(is_callable($this->customAttack)){
                return
call_user_func($this->customAttack);
            }
           
           
$this->feet = false;
        }
    }

   
$p = new Person('Bob');

   
   
$p->customAttack =
                function(){
                   
                    echo
$this; // Notice: Undefined variable: this
                   
                    #$this = new Class() // FATAL ERROR
                   
                    // Trick to assign the variable '$this'
                   
extract(array('this' => requesting_class())); // Determine what class is responsible for making the call to Closure
                   
                   
var_dump( $this  );  // Passive reference works
                   
var_dump( $$this ); // Added to class:  function __toString(){ return 'this'; }
                   
                   
$name = $this('name'); // Success
                   
echo $name;            // Outputs: Bob
                   
echo '<br />';
                    echo $
$this->name;
                   
                   
call_user_func_array(array($this, 'deflect'), array()); // SUCCESSFULLY CALLED
                   
                    #$this->head = 0; //** FATAL ERROR: Using $this when not in object context
                   
$$this->head = 0// Successfully sets value
                   
               
};
 
   
print_r($p);
   
   
$p->shoot();
   
   
print_r($p);

   
    die();

?>
Hayley Watson 12-Apr-2010 01:53
In the code

<?php
function new_counter()
{
   
$counter = mt_rand();
    return function()use(&
$counter)
    {
        return ++
$counter;
    };
}

$t1 = new_counter();
$t2 = new_counter();

echo
$t1(),"\n";
echo
$t1(),"\n";
echo
$t2(),"\n";
echo
$t2(),"\n";
echo
$t1(),"\n";
echo
$t1(),"\n";
?>

The variable $counter is local to new_counter() and is used by reference by the returned lambda function.

Because $counter is not static, a new variable is created each time new_counter() is called.

But because the lambda function uses a REFERENCE to the $counter variable - and not a new local variable with a copy of the value $counter had when the lambda function was constructed - the $counter variable created when new_counter() ran still exists (because a reference to it still exists).

Every lambda function has a variable reference "hardwired" into it. That variable therefore persists across calls to the lambda function - rather like a static variable.

But that variable is only LOCAL to the new_counter() function that created it. As soon as new_counter() returns, it gives up its reference to $counter. When new_counter() is called again, it gets allocated a NEW $counter variable and gives a reference to THAT variable to the lambda function it constructs.

So the lambda functions in $t1 and $t2 each have their OWN $counter variable - separate from the other's, which persists from one call to the next.

The effect is very similar to declaring and initialising $counter as static within the lambda function - and then it doesn't need to use anything from new_counter() - but you can't initialise a static variable with a function call like mt_rand()!

Pending a decision on what it should mean, $this is not currently (as of 5.3.2) usable within anonymous functions.

There are roughly two positions (plus attempts at compromise), that can be called "early" and "late".

Early: $this refers to the object in whose scope the anonymous function is constructed.
<?php
class Creator
{
   public function
make_anonymous()
   {
       return function()
       {
           return
$this;
       };
   }
}

class
Caller
{
   public
$p;
   public function
call_anonymous($f)
   {
      
$this->p = $f();
   }
}

$alpha = new Creator;
$omega = new Caller;
$omega->call_anonymous($alpha->create_anonymous());
// $omega->p === $alpha
?>

Late: $this refers to the object in whose scope the anonymous function is called.

<?php
class Creator
{
   public function
make_anonymous()
   {
       return function()
       {
           return
$this;
       };
   }
}

class
Caller
{
   public
$p;
   public function
call_anonymous($f)
   {
      
$this->p = $f();
   }
}

$alpha = new Creator;
$omega = new Caller;
$omega->call_anonymous($alpha->create_anonymous());
// $omega->p === $omega
?>

So until this is cleared up, $this won't work in an anonymous function. (Personally, I favour the early method; otherwise the anonymous function - and therefore its Creator - has access to all of the Caller's private properties.)
housni dot yakoob at gmail dot com 14-Mar-2010 04:22
If you want to make sure that one of the parameters of your function is a Closure, you can use Type Hinting.
see: http://php.net/manual/en/language.oop5.typehinting.php

Example:
<?php

class TheRoot
{
    public function
poidh($param) {
        echo
"TheRoot $param!";
    }  

}

class
Internet
{
   
# here, $my_closure must be of type object Closure
   
public function run_my_closure($bar, Closure $my_closure) {
       
$my_closure($bar);
    }  
}

$Internet = new Internet();
$Root = new TheRoot();

$Internet->run_my_closure($Root, function($Object) {
   
$Object->poidh(42);
});

?>
The above code simply yields:
"TheRoot 42!"

NOTE: If you are using namespaces, make sure you give a fully qualified namespace.

print_r() of Internet::run_my_closure's $my_closure
<?php
Closure Object
(
    [
parameter] => Array
        (
            [
$Object] =>
        )

)
?>

var_dump() of Internet::run_my_closure's $my_closure
<?php
object
(Closure)#3 (1) {
 
["parameter"]=>
  array(
1) {
    [
"$Object"]=>
   
string(10) ""
 
}
}
?>
aaron at afloorabove dot com 05-Mar-2010 08:42
Anonymous functions are great for events!

<?php

class Event {

  public static
$events = array();
 
  public static function
bind($event, $callback, $obj = null) {
    if (!
self::$events[$event]) {
     
self::$events[$event] = array();
    }
   
   
self::$events[$event][] = ($obj === null)  ? $callback : array($obj, $callback);
  }
 
  public static function
run($event) {
    if (!
self::$events[$event]) return;
   
    foreach (
self::$events[$event] as $callback) {
      if (
call_user_func($callback) === false) break;
    }
  }

}

function
hello() {
  echo
"Hello from function hello()\n";
}

class
Foo {
  function
hello() {
    echo
"Hello from foo->hello()\n";
  }
}

class
Bar {
  function
hello() {
    echo
"Hello from Bar::hello()\n";
  }
}

$foo = new Foo();

// bind a global function to the 'test' event
Event::bind("test", "hello");

// bind an anonymous function
Event::bind("test", function() { echo "Hello from anonymous function\n"; });

// bind an class function on an instance
Event::bind("test", "hello", $foo);

// bind a static class function
Event::bind("test", "Bar::hello");

Event::run("test");

/* Output
Hello from function hello()
Hello from anonymous function
Hello from foo->hello()
Hello from Bar::hello()
*/

?>
ljackson at jjcons dot com 21-Feb-2010 04:46
appears kwilson at shuttlebox dot net that you may have just made unintended side effect. Note that adding the global $variable to your test function make the closure function echo second rather than first So the anonymous function works as expected with respect to globals.

<?php
    $variable
= "first";

   
$closure = function() {
        global
$variable;

        echo
$variable . "\n";
    };

   
$closure();

    function
test($closure)
    {
        global
$variable; //Note the scope added here
       
$variable = "second";

       
$closure();
    }

   
test($closure);
?>

prints:
first
second

tested with php 5.3.1
kwilson at shuttlebox dot net 21-Jan-2010 01:24
Using the global keyword apparently pulls variables from the scope where the function was created, not where it is executed.

Example:

<?php
    $variable
= "first";
   
   
$closure = function() {
        global
$variable;
       
        echo
$variable . "\n";
    };
   
   
$closure();
   
    function
test($closure)
    {
       
$variable = "second";
       
       
$closure();
    }
   
   
test($closure);
?>

Will print:

first
first
puskulcu at gmail dot com 14-Dec-2009 06:46
hello there!
here is a little code which shows use of the closures as event handlers:

<?php

 
class Button
 
{
    public
$OnBeforeClick;
    public
$OnAfterClick;
    public
$Name;

    function
Button()
    {
     
$this->Name = 'MyButton';   
    }
   
    public function
Click()
    {
     
$this->DoBeforeClick();
     
      echo
'Click!';
     
     
$this->DoAfterClick();
    }

    private function
DoBeforeClick()
    {
      if (isset(
$this->OnBeforeClick))
      {
       
$Event = $this->OnBeforeClick;
       
$Event($this);
      }
    }

    private function
DoAfterClick()
    {
      if (isset(
$this->OnAfterClick))
      {
       
$Event = $this->OnAfterClick;
       
$Event($this);
      }
    }
  }
 
 
//eclipse may warn here about syntax error but no problem, it runs well.
 
$BeforeClickEventHandler = function($Sender) { echo $Sender->Name . ' (Before Click)'; }; 
 
$AfterClickEventHandler = function($Sender) { echo $Sender->Name . ' (After Click)'; }; 
 
 
$MyWidget = new Button();
 
$MyWidget->OnBeforeClick = $BeforeClickEventHandler;
 
$MyWidget->OnAfterClick = $AfterClickEventHandler;
 
$MyWidget->Click();

?>

output:
MyButton (Before Click)
Click!
MyButton (After Click)

i hope you find this useful.
regards.
emre
rob at ubrio dot us 25-Nov-2009 04:20
You can always call protected members using the __call() method - similar to how you hack around this in Ruby using send.

<?php

class Fun
{
 protected function
debug($message)
 {
   echo
"DEBUG: $message\n";
 }

 public function
yield_something($callback)
 {
   return
$callback("Soemthing!!");
 }

 public function
having_fun()
 {
  
$self =& $this;
   return
$this->yield_something(function($data) use (&$self)
   {
    
$self->debug("Doing stuff to the data");
    
// do something with $data
    
$self->debug("Finished doing stuff with the data.");
   });
 }

 
// Ah-Ha!
 
public function __call($method, $args = array())
 {
   if(
is_callable(array($this, $method)))
     return
call_user_func_array(array($this, $method), $args);
 }
}

$fun = new Fun();
echo
$fun->having_fun();

?>
mike at blueroot dot co dot uk 28-Oct-2009 03:40
To recursively call a closure, use this code.

<?php
$recursive
= function () use (&$recursive){
   
// The function is now available as $recursive
}
?>

This DOES NOT WORK

<?php
$recursive
= function () use ($recursive){
   
// The function is now available as $recursive
}
?>
kukoman at pobox dot sk 13-Oct-2009 12:22
be aware of  Fatal error: Using $this when not in object context when using in closures

http://wiki.php.net/rfc/closures/removal-of-this
gerard at visei dot nl 07-Oct-2009 02:41
The text above the third example tries to explain that anonymous functions can inherit variables from the parent scope, but fails to properly explain how this is done: namely using the "use" keyword in the function definition.

The following page has a much more detailed explanation of closures in PHP 5.3:
http://wiki.php.net/rfc/closures
dave at mausner dot us 10-Aug-2009 09:34
Ulderico had it almost right.  To avoid confusing the interpreter, when using a simple closure stored in a $variable, you must invoke the nameless function using the function syntax.

<?php
$helloworld
= function(){
    return
"each hello world is different... ".date("His");
};

echo
$helloworld( );
?>

Note the empty actual-parameter list in the "echo".  NOW IT WORKS.
Anonymous 02-Aug-2009 09:50
If you want to check whether you're dealing with a closure specifically and not a string or array callback you can do this:

<?php
$isAClosure
= is_callable($thing) && is_object($thing);
?>
tom at r dot je 28-Jul-2009 10:51
Unfortunately, you can't get a pointer to a function, the only function pointers are ones which use anonymous functions as they're created.

This wont work:

<?php
$info
= phpinfo;
$info();

//or

function foo() {
echo
'bar';
}

$foo = foo;
$foo();
?>

Because of the behavior of $foo(), it will assume $foo is a string, and try to run the function with the name stored in the string.
mcm dot matt at gmail dot com 30-Jun-2009 12:49
Example using uasort.

<?php
// Usual method.
function cmp($a, $b) {
    return(
$a > $b);
}
uasort($array, 'cmp');

// New
uasort($array, function($a, $b) {
    return(
$a > $b);
});
?>
a dot schaffhirt at sedna-soft dot de 18-Jun-2009 09:55
When using anonymous functions as properties in Classes, note that there are three name scopes: one for constants, one for properties and one for methods. That means, you can use the same name for a constant, for a property and for a method at a time.

Since a property can be also an anonymous function as of PHP 5.3.0, an oddity arises when they share the same name, not meaning that there would be any conflict.

Consider the following example:

<?php
   
class MyClass {
        const
member = 1;
       
        public
$member;
       
        public function
member () {
            return
"method 'member'";
        }
       
        public function
__construct () {
           
$this->member = function () {
                return
"anonymous function 'member'";
            };
        }
    }
   
   
header("Content-Type: text/plain");
   
   
$myObj = new MyClass();

   
var_dump(MyClass::member);  // int(1)
   
var_dump($myObj->member);   // object(Closure)#2 (0) {}
   
var_dump($myObj->member()); // string(15) "method 'member'"
   
$myMember = $myObj->member;
   
var_dump($myMember());      // string(27) "anonymous function 'member'"
?>

That means, regular method invocations work like expected and like before. The anonymous function instead, must be retrieved into a variable first (just like a property) and can only then be invoked.

Best regards,

 
show source | credits | sitemap | contact | advertising | mirror sites