Анонимные функции

Анонимные функции, также известные как замыкания (closures), позволяют создавать функции, не имеющие определенных имен. Они наиболее полезны в качестве значений callback-параметров, но также могут иметь и множество других применений.

Пример #1 Пример анонимной функции

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

Замыкания также могут быть использованы в качестве значений переменных; PHP автоматически преобразует такие выражения в экземпляры внутреннего класса Closure. Присвоение замыкания переменной использует тот же синтаксис, что и для любого другого присвоения, включая завершающую точку с запятой:

Пример #2 Пример присвоения анонимной функции переменной

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

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

Замыкания могут также наследовать переменные из родительской области видимости. Любая подобная переменная должна быть объявлена в заголовке функции. Наследование переменных из родительской области видимости не то же самое, что использование глобальных переменных. Глобальные переменные существуют в глобальной области видимости, которая не меняется, вне зависимости от того, какая функция выполняется в данный момент. Родительская область видимости - это функция, в которой было объявлено замыкание (не обязательно та же самая, из которой оно было вызвано). Смотрите следующий пример:

Пример #3 Замыкания и область видимости

<?php
// Базовая корзина покупок, содержащая список добавленных
// продуктов и количество каждого продукта. Включает метод,
// вычисляющий общую цену элементов корзины с помощью
// 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;

// Добавляем несколько элементов в корзину
$my_cart->add('butter'1);
$my_cart->add('milk'3);
$my_cart->add('eggs'6);

// Выводим общую сумму с 5% налогом на продажу.
print $my_cart->getTotal(0.05) . "\n";
// Результатом будет 54.29
?>

Анонимные функции реализованы с помощью класса Closure.

Список изменений

Версия Описание
5.4.0 Стало возможным использовать $this в анонимных функциях.
5.3.0 Появление анонимных функций.

Примечания

Замечание: Совместно с замыканиями можно использовать функции func_num_args(), func_get_arg() и func_get_args().

Коментарии

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,
2009-06-19 05:55:16
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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);
});
?>
2009-06-30 08:49:05
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Автор:
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);
?>
2009-08-03 05:50:52
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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.
2009-08-10 17:34:35
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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
2009-10-07 10:41:46
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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
2009-10-13 08:22:11
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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
}
?>
2009-10-28 10:40:35
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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();

?>
2009-11-25 12:20:03
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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
2009-12-14 14:46:49
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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
2010-01-21 09:24:38
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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
2010-02-22 00:46:26
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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()
*/

?>
2010-03-05 16:42:57
http://php5.kiev.ua/manual/ru/functions.anonymous.html
If you want to make sure that one of the parameters of your function is a Closure, you can use Type Hinting.
see: language.oop5.typehinting

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($barClosure $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""
 
}
}
?>
2010-03-14 11:22:21
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Автор:
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->$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->$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.)
2010-04-12 21:53:25
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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();

?>
2010-05-14 23:55:27
http://php5.kiev.ua/manual/ru/functions.anonymous.html
$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->$self->f();
        };
    }
}

$foo = new Foo();
$closure $foo->getClosureUsingPrivates();
echo 
$closure() . "\n"// Prints 45 as expected
?>
2010-06-11 13:50:36
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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

function.call-user-func
function.call-user-func-array

If you're wondering if $some_var1 and $some_var2 are still visible by using the call_user_func, yes, they are available.
2010-07-20 01:56:51
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Автор:
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

?>
2010-08-08 21:53:08
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Автор:
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(hostNameuserNamepassword);
        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($sqlarray_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);

?>
2010-08-19 06:21:05
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Автор:
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 == || $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 == || $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 == || $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 $f(5);
};

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

?>
2010-10-22 10:00:10
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Автор:
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)
2010-10-28 03:54:33
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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 ;)
2011-02-24 09:51:10
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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.
2011-03-06 16:36:43
http://php5.kiev.ua/manual/ru/functions.anonymous.html
<?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');

?>
2011-08-05 11:23:52
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Автор:
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){ ... });
2011-08-13 16:24:35
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Using closure to encapsulate environment
<?php
    $fib 
= function($n) use(&$fib) {
        if(
$n == || $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 == || $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 
?>
2011-08-27 23:15:39
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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 ;)
2012-01-24 16:46:19
http://php5.kiev.ua/manual/ru/functions.anonymous.html
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");
    };
?>
2012-03-16 06:42:45
http://php5.kiev.ua/manual/ru/functions.anonymous.html
I fell uncomfortable with php's way to pass callbacks ahead. It's just a personal opinion but i think the structure array($object, 'method') a little bit ugly. In some special cases i would like to do something more verbose, like that:

<?php
    $sortedArray 
ArrayServices::sort($arrayOfPerson$sortPerson->byName);
?>

Here, "$sortPerson->byName" is a pointer to a function that receives 2 instances of Person and return true if the name of the first is "bigger" than the second. "ArrayServices::sort" is a function that can sort any kind of array using different criterias, it uses the function passed on the second parameter to compare two items on the array

I am able do that defining a simple abstract class which gives the ability to it's children to expose their methods as closures using __get() magic funtion.

<?php
abstract class ClosureExposerObject
{
    public function 
__get($methodName)
    {
        if (
is_callable(
                array(
$this$methodName)))
        {
            return function() use (
$methodName)
            {
               
$args func_get_args(); 
                return 
call_user_func_array(array($this$methodName), $args);
            };
        }
        else
        {
           
$className get_class($this);
            throw new 
BadMethodCallException("$method is not a callable at $className class.");
        }
    }
}
?>

Now it is possible to define a class SortPerson so that i could use it like in the first code snippet.

<?php

class SortPerson extends ClosureExposerObject
{
    public function 
byName(Person p1Person p2)
    {
        return 
p1->getName() > p2->getName();
    }
   
    public function 
byAge(Person p1Person p2)
    {
        return 
p1->getAge() > p2->getAge();
    }
   
    public function 
bySurName(Person p1Person p2)
    (...)
}

?>

I just needed to extend ClosureExposerObject and do nothing more. 

Some observations: SortPerson is a service class but i decided not to implement it with static methods. It is a personal matter but i really dont like to implement such small classes with statics. Also i have inverted some naming conventions (class names as substantives and methods as verbs) but in some very special cases i thing that it actually helps readability.
2012-12-30 00:05:29
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Beware of scope!  $this refers to the class that the function was defined within.

 ----------- Example #1 - Doesn't work (Notice: Undefined variable: this) ----------- 
<?php

$callableFunc 
= function () {
   
var_dump($this);
};

call_user_func($callableFunc);

?>

 ----------- Example #2 - Doesn't work (Notice: Undefined variable: this) ----------- 
<?php
class myClass {
    public function 
execute($func) {
        if (
is_callable($func)) {
           
call_user_func($func);
        }
    }
}

$class = new myClass();
$class->execute(function () {
   
var_dump($this);
});
?>

 ----------- Example #3 - Works! ----------- 
<?php
class myClass {
    public function 
getMyExecutableFunction() {
        return function () {
           
var_dump($this);
        };
    }

    public function 
execute($func) {
        if (
is_callable($func)) {
           
call_user_func($func);
        }
    }
}

$class = new myClass();
$class->execute($class->getMyExecutableFunction()); //object(myClass)[1]
?>

$this is not available in a static method!
2013-01-31 18:34:35
http://php5.kiev.ua/manual/ru/functions.anonymous.html
just in case you ever want to change a member function run time

<?php 

class t
{
    var 
$num;
   
    var 
$dynamic_function;
   
    public function 
dynamic_function()
    {
       
$func $this->dynamic_function
       
       
$func($this); 
    }
}

$p = new t();

$p->num 5;

$p->dynamic_function = function($this_ref// param cannot be named $this
{
    echo 
$this_ref->num++.'<br />';
};

$p->dynamic_function(); // CALL YOUR DYNAMIC FUNCTION

$p->dynamic_function = function($this_ref// NEW DYNAMIC fUNCRION
{
    echo 
$this_ref->num.'<br />';
   
   
$this_ref->num *= 3;
};

$p->dynamic_function(); // CALL DYNAMIC FUNCTION

echo $p->num// display number

exit;

?>

output:
5
6
18
2013-06-03 09:54:08
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Some hosts are installing the eAccelerator opcode cache with PHP 5.4, and current production versions of this opcode cache break closures. If you find that your nice, working closures break when you load your code to a hosted website, check for eAccelerator (e.g. by calling phpinfo() and checking the output).

Simple fixes include:

* disabling eAccelerator and opcode caching
* replacing eAccelerator with Zend's opcache
* reverting to PHP 5.3

Apparently, the eAccelerator project has solved this issue, but hosts move slowly so I recommend removing eAccelerator from the equation for now.
2013-10-09 02:10:10
http://php5.kiev.ua/manual/ru/functions.anonymous.html
You cannot use closures as a class variable member in its declaration like this:

<?php

class foo
{
    public 
$bar = function() {
        echo 
"baz";
    };
}

?>

I don't know why but this will raise a
Parse error: syntax error, unexpected 'function' (T_FUNCTION)

(used PHP 5.4)
2013-11-08 10:51:47
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Example: 

<?php
$a 
213;

$f = function() use ($a){
    echo 
$a;
};

$a 144;
echo 
$a;

$f();
?>

Result: 
144
213
2013-11-26 15:06:17
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Автор:
In case you were wondering (cause i was), anonymous functions can return references just like named functions can.  Simply use the & the same way you would for a named function...right after the `function` keyword (and right before the nonexistent name).

<?php
    $value 
0;
   
$fn = function &() use (&$value) { return $value; };

   
$x =& $fn();
   
var_dump($x$value);        // 'int(0)', 'int(0)'
   
++$x;
   
var_dump($x$value);        // 'int(1)', 'int(1)'
2013-12-14 01:42:26
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Beware that since PHP 5.4 registering a Closure as an object property that has been instantiated in the same object scope will create a circular reference which prevents immediate object destruction:
<?php

class Test
{
    private 
$closure;

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

    public function 
__destruct()
    {
        echo 
"destructed\n";
    }
}

new 
Test;
echo 
"finished\n";

/*
 * Result in PHP 5.3:
 * ------------------
 * destructed
 * finished
 *
 * Result since PHP 5.4:
 * ---------------------
 * finished
 * destructed
 */

?>

To circumvent this, you can instantiate the Closure in a static method:
<?php

public function __construct()
{
   
$this->closure self::createClosure();
}

public static function 
createClosure()
{
    return function () {
    };
}

?>
2014-01-09 18:41:01
http://php5.kiev.ua/manual/ru/functions.anonymous.html
In 5.3, $this cannot be used in an anonymous function, though you can simply assign $this to another variable and pass that into the function in the use section, This quick and dirty hack works for at least calling public functions and accessing public variables of the parent class.

<?php

class Example {
    public 
$blah;
    function 
foo() {
       
$that $this;
       
$tmp = function() use ($that) {
             return 
$that->blah;
         }
        return 
$tmp;
    }
}

$test = new Example();
$example->blah "whatever";
echo 
$example->foo(); // prints "whatever"
2014-01-21 07:48:43
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Some comparisons of PHP and JavaScript closures.

=== Example 1 (passing by value) ===
PHP code:
<?php
$aaa 
111;
$func = function() use($aaa){ print $aaa; };
$aaa 222;
$func(); // Outputs "111"
?>

Similar JavaScript code:
<script type="text/javascript">
var aaa = 111;
var func = (function(aaa){ return function(){ alert(aaa); } })(aaa);
aaa = 222;
func(); // Outputs "111"
</script>

Be careful, following code is not similar to previous code:
<script type="text/javascript">
var aaa = 111;
var bbb = aaa;
var func = function(){ alert(bbb); };
aaa = 222;
func(); // Outputs "111", but only while "bbb" is not changed after function declaration

// And this technique is not working in loops:
var functions = [];
for (var i = 0; i < 2; i++)
{
    var i2 = i;
    functions.push(function(){ alert(i2); });
}
functions[0](); // Outputs "1", wrong!
functions[1](); // Outputs "1", ok
</script>

=== Example 2 (passing by reference) ===
PHP code:
<?php
$aaa 
111;
$func = function() use(&$aaa){ print $aaa; };
$aaa 222;
$func(); // Outputs "222"
?>

Similar JavaScript code:
<script type="text/javascript">
var aaa = 111;
var func = function(){ alert(aaa); };
aaa = 222; // Outputs "222"
func();
</script>
2014-02-20 13:20:18
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Автор:
Please note that while You can assign a closure to an array key with the method

$array['key'] = function() { return $whatever; };

You cannot do the same with the array assignment operator.

So

$array = Array(
  'key' => function() { return $whatever; }
);

will NOT work.
(This is indeed awkward.)
2014-02-25 10:26:35
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Haven't seen it documented anywhere but PHP 5.4 now allows accessing private and protected members of an object if it's passed into a lambda function:

<?php
class Scope
{
    protected 
$property 'default';
   
// or even
    // private $property = 'default';

   
public function run()
    {
       
$self $this;
       
$func = function() use ($self) {
           
$self->property 'changed';
        };

       
$func();
       
var_dump($this->property);
    }
}

$scope = new Scope();
$scope->run();
?>

When running the file under PHP 5.3 you get the following error message:
 * Fatal error: Cannot access protected property Scope::$property in ./file.php on line 11

PHP 5.4, however, does not complain and outputs "changed" as expected. 

Not sure why it's like that but I suspect it has something to do with 5.4 supporting passing $this into lambda functions.

Speaking of which, something to remember is that the following won't work:
<?php
$func 
= function() use ($this) {
   
$this->property 'changed';
};
?>
The error you'll get is:
 * PHP Fatal error:  Cannot use $this as lexical variable in ./file.php on line 9

You have to totally omit the use statement for it to work:
<?php
$func 
= function() {
   
$this->property 'changed';
};
?>
2014-03-05 14:33:59
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Автор:
Doesn't anyone else think Closure is used here with an inappropriate meaning?

Isn't closure just the concept of being able to reference the outer function environment from the inner function, as in example #3?

It's commonly used with anonymous functions, but from what I know it's not the same thing as an anonymous function.
"Lambda functions" might be another name for anonymous functions, not "Closures".

I mean, a named function could employ closure too.
And anonymous functions don't necessarily support closure in all languages.
2014-10-10 19:12:10
http://php5.kiev.ua/manual/ru/functions.anonymous.html
<?php
   
/*
    (string) $name Name of the function that you will add to class.
    Usage : $Foo->add(function(){},$name);
    This will add a public function in Foo Class.
    */
   
class Foo
   
{
        public function 
add($func,$name)
        {
           
$this->{$name} = $func;
        }
        public function 
__call($func,$arguments){
           
call_user_func_array($this->{$func}, $arguments); 
        }
    }
   
$Foo = new Foo();
   
$Foo->add(function(){
        echo 
"Hello World";
    },
"helloWorldFunction");
   
$Foo->add(function($parameterone){
        echo 
$parameterone;
    },
"exampleFunction");
   
$Foo->helloWorldFunction(); /*Output : Hello World*/
   
$Foo->exampleFunction("Hello PHP"); /*Output : Hello PHP*/
?>
2015-06-20 00:48:04
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Here is a simple example to use clousers
<?php 

function add($x,$y){
    return 
$x+$y();   
}

echo 
add(3,function(){
    return 
5;
});

?>

prints 8
2015-12-29 21:29:14
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Автор:
Will result in a "Parse error: syntax error, unexpected '[', expecting ',' or ')' ... "

<?php

$fruits 
= ['apples''oranges'];
$example = function () use ($fruits[0]) {
    echo 
$fruits[0]; 
};
$example();
?>

Would have to do this:

<?php

$fruits 
= ['apples''oranges'];
$example = function () use ($fruits) {
    echo 
$fruits[0]; // will echo 'apples'
};
$example();

?>

Or this instead:

<?php

$fruits 
= ['apples''oranges'];
$fruit $fruits[0];
$example = function () use ($fruit) {
    echo 
$fruit// will echo 'apples'
};
$example();
2016-05-25 22:46:40
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Supported by PHP 7.0+ only.
<?php
   
(function($name){
        echo 
'My name is ' $name;
    })(
'Wu Xiancheng');
?>
2016-09-17 13:36:42
http://php5.kiev.ua/manual/ru/functions.anonymous.html
A simple trick to call an anonymous function from inside itself.
Please note the use of a global variable and, therefore, the limitations of this hack:

<?php
   
// Counts recursively from $x down to 0
   
$ref = function($x) {
        global 
$ref// reference to global that references this anonymous function
       
echo "Counting $x <br/>";
        if (
$x 0) {
           
$ref($x 1);
        }
    };

   
$ref(3);
?>

OUTPUT:

Counting 3 
Counting 2 
Counting 1 
Counting 0
2016-12-31 17:33:59
http://php5.kiev.ua/manual/ru/functions.anonymous.html
PERFORMANCE BENCHMARK 2017!

I decided to compare a single, saved closure against constantly creating the same anonymous closure on every loop iteration. And I tried 10 million loop iterations, in PHP 7.0.14 from Dec 2016. Result:

a single saved closure kept in a variable and re-used (10000000 iterations): 1.3874590396881 seconds

new anonymous closure created each time (10000000 iterations): 2.8460240364075 seconds

In other words, over the course of 10 million iterations, creating the closure again during every iteration only added a total of "1.459 seconds" to the runtime. So that means that every creation of a new anonymous closure takes about 146 nanoseconds on my 7 years old dual-core laptop. I guess PHP keeps a cached "template" for the anonymous function and therefore doesn't need much time to create a new instance of the closure!

So you do NOT have to worry about constantly re-creating your anonymous closures over and over again in tight loops! At least not as of PHP 7! There is absolutely NO need to save an instance in a variable and re-use it. And not being restricted by that is a great thing, because it means you can feel free to use anonymous functions exactly where they matter, as opposed to defining them somewhere else in the code. :-)
2017-02-07 21:36:37
http://php5.kiev.ua/manual/ru/functions.anonymous.html
Автор:
If you want to create and then immediately call a closure directly, in-line, and immediately get its return value (instead of the closure reference itself), then the proper syntax is as follows:

<?php

$a 
'foo'$b 'bar';
$test = (function() use($a,$b) { return $a $b; })();
echo 
$test;

?>

As for why you would want to do that? Well, that's up to you. I'm sure there are some legitimate reasons. It's a pretty common pattern in some other famous scripting languages. But if you're doing this in PHP, you should think carefully and ask yourself if you really have a good reason for it, or if you should just go and re-structure your code instead. ;-)
2017-02-07 21:48:10
http://php5.kiev.ua/manual/ru/functions.anonymous.html
One way to call a anonymous function recursively is to use the USE keyword and pass a reference to the function itself:

<?php
$count 
1;
$add = function($count) use (&$add){
   
$count += 1;
    if(
$count 10$count $add($count); //recursive calling
   
return $count;
};
echo 
$add($count); //Will output 10 as expected
?>
2017-04-29 20:35:07
http://php5.kiev.ua/manual/ru/functions.anonymous.html

    Поддержать сайт на родительском проекте КГБ