47

Possible Duplicate:
How do you use anonymous functions in PHP?

Why should i use an anonymous function? I mean, what's the real deal using it? I just don't really get this. I mean, you use function to make the code more clean or to use it more than once. But Anonymous functions just don't do neither the first nor the second. I googled them and i couldn't find anyone asking the same problem.

Community
  • 1
  • 1
Shoe
  • 74,840
  • 36
  • 166
  • 272
  • 1
    Can you remove closures from the title? It's slightly tangential to the meat of your question. – Bradley Kreider Nov 10 '10 at 18:05
  • @rox0r - you really think closures are unrelated? seemed appropriate to me so i incorporated into my answer in way i hope is useful for demonstration. obviously you can have lambda funcs without closures, but not vice-versa – jon_darkstar Nov 10 '10 at 18:17
  • @jon: I think they are related, but his intent seemed to be focused on just named vs anon. functions. I think it is good that you mentioned closures, i just thought it was misleading in the title. – Bradley Kreider Nov 10 '10 at 18:24

9 Answers9

59

I would say that anonymous functions show their beauty when there is good library classes/functions that use them. They are not that sexy by themselves. In the world of .net there is technology called LINQ that makes huge use of then in very idiomatic manner. Now back to PHP.

First example, sort:

uasort($array, function($a, $b) { return($a > $b); });

You can specify complex logic for sorting:

uasort($array, function($a, $b) { return($a->Age > $b->Age); });

Another example:

$data = array( 
        array('id' => 1, 'name' => 'Bob', 'position' => 'Clerk'), 
        array('id' => 2, 'name' => 'Alan', 'position' => 'Manager'), 
        array('id' => 3, 'name' => 'James', 'position' => 'Director') 
); 

$names = array_map( 
        function($person) { return $person['name']; }, 
        $data 
);

You see how nicely you can produce array of names.

Last one:

array_reduce(
   array_filter($array, function($val) { return $val % 2 == 0; },
   function($reduced, $value) { return $reduced*$value; }
)

It calculates product of even numbers.

Some philosophy. What is function? A unit of functionality that can be invoked and unit of code reuse. Sometimes you need only the first part: ability to invoke and do actions, but you don't want to reuse it at all and even make it visible to other parts of code. That's what anonymous functions essentially do.

Andrey
  • 59,039
  • 12
  • 119
  • 163
22

It is useful especially for callbacks:

array_walk($myArray, function($value, $key) {
   // do something
});
netcoder
  • 66,435
  • 19
  • 125
  • 142
  • 3
    how is it better then `foreach`? This is meaningless example. It shows something that can be done using another construct even easier. it doesn't show usefulness of anonymous function. really. – Andrey Nov 10 '10 at 18:05
  • 3
    The OP didn't ask what was better. It asked what is it useful for. The answer: **callbacks**. If you want to provide 1000 examples, feel free to do it in your own answer. – netcoder Nov 10 '10 at 18:10
  • 1
    Right. "It asked what is it useful for." in your example they are not useful at all. I am not saying that you should provide 1000 examples. One could be enough, but a representative and relevant one. – Andrey Nov 10 '10 at 18:19
  • 11
    @Andrey: If you don't feel my answer is useful enough, don't upvote it, and provide what you think is a better answer. End of story. – netcoder Nov 10 '10 at 18:24
7

You normally use anonymous functions for functions which you need only once. This way you do not pollute the function namespace and don't invent strange function names like array_walk_callback1.

Gordon
  • 312,688
  • 75
  • 539
  • 559
NikiC
  • 100,734
  • 37
  • 191
  • 225
  • 2
    Hopefully you never invent those strange function names. Things like `returnUsefulDataFromArray` would be more useful :) – gnarf Nov 10 '10 at 17:59
5

Perhaps most obvious reason is the use of callbacks. Take usort() function for example. There's no point introducing a one-line function, that will be used once and once only. Anonymous function (usually) fits better this task.

Shoe
  • 74,840
  • 36
  • 166
  • 272
Mchl
  • 61,444
  • 9
  • 118
  • 120
3

You can pass anonymous functions around by saving them in a variable.

$a=function() {
    echo 'hello world';
};

This means you can also use them more than once.

bcosca
  • 17,371
  • 5
  • 40
  • 51
  • 2
    Why don't just declare a function then? – Shoe Nov 10 '10 at 18:07
  • "more than once". Can't you use regular function more then once? – Andrey Nov 10 '10 at 18:07
  • 5
    You ought to remember that declared functions are global, while anonymous functions are not. You don't want to pollute the global namespace with use-once and trivial functions – bcosca Nov 10 '10 at 18:08
  • 7
    Also, variable functions can be destroyed using `unset`, while global functions cannot. – netcoder Nov 10 '10 at 18:19
  • @netcoder What is the use of destroying a variable, except for freeing up the name? Is `unset` similar to `myVariable = null;` in Java, where it will eventually free up memory as well? – Honinbo Shusaku Jul 10 '15 at 19:00
  • 1
    @Abdul: Scoping is very different in PHP vs Java. In fact, in PHP scoping is limited to global scope and function scope. e.g.: `{ $foo = "bar"; } echo $foo;` works in PHP. `{ String foo = "bar"; } System.out.println(foo);` doesn't in Java. Un-setting variables can be useful to prevent polluting the scope that may eventually introduce programming errors. That applies to both variables and variable functions. – netcoder Jul 10 '15 at 19:06
2

There are times when you MUST use a function. Thus closures keep code clean by not having to fill your libraries with function declarations that are only used in one place. Closures are similar to style="" and classes in CSS. Sure you can create a boatload of classes for every single one off style you have, or you can embed them in place since you do not use it elsewhere and decrease the bloat of your CSS files.

It's not a necessity, though, so if you feel the need to explicitly declare functions you are free to do that.

Shoe
  • 74,840
  • 36
  • 166
  • 272
methodin
  • 6,717
  • 1
  • 25
  • 27
  • 1
    But if i use that function just once why shouldn't just don't declare any functions at all? Neither the normal nor the anonymous one? – Shoe Nov 10 '10 at 17:57
  • And do you really want your HTML polluted with tags describing presentation, as opposed to content? – gnarf Nov 10 '10 at 18:00
  • 2
    Anonymous functions help when you MUST USE A FUNCTION - like in usort, array_map etc... in these cases traditionally you would have to create a function somewhere in the code and pass the name of the function in. With anonymous functions you can just declare it on the fly. It also helps with callbacks. Your examples seem to indicate you are thinking of anonymous functions as just ways to group code - which they can be, but that's not the real purpose of them. – methodin Nov 10 '10 at 18:00
  • @charlie Sometimes you need to have a function to pass in as a parameter. That's why people mention callbacks. When callbacks are used, you have to pass a function to the callback. – Bradley Kreider Nov 10 '10 at 18:03
  • @rox0r I got that, but you could also use a string with the function name as callback. Anyway thanks, know i know. – Shoe Nov 10 '10 at 18:09
  • @charlie: Do you mean function name instead of string? Yes. I was responding to "why declare any functions at all" that is above. – Bradley Kreider Nov 10 '10 at 18:18
2

If you need to create a callback (to make a concrete example, lets say its a comparison function for usort) anonymous functions are usually a good way to go. Particularly if the definition of the function is dependent on a few inputs (by this i mean a closure, which is NOT synonymous with anon function)

function createCallback($key, $desc = false)
{
    return $desc ? 
       function($a, $b) use ($key) {return $b[$key] - $a[$key];} :
       function($a, $b) use ($key) {return $a[$key] - $b[$key];};
}


usort($myNestedArray, createCallback('age'));  //sort elements of $myNestedArray by key 'age' ascending
usort($myNestedArray, createCallback('age', true); //descending
jon_darkstar
  • 16,398
  • 7
  • 29
  • 37
1

In my opinion, anonymous functions are best used as callbacks for functions. Many of the php array functions will use these as parameters.

They could also be used in observer / event listener patterns.

gnarf
  • 105,192
  • 25
  • 127
  • 161
1

Using jQuery/Javascript you can use it to define custom event callbacks. Take a look at how the jQuery core handles AJAX.

Example of jQuery using anonymous functions for event callbacks:

$.ajax({
  url: 'ajax/test.html',
  complete: function(data) {
    $('.result').html(data);
    alert('Load was performed.');
  }
});

Other events w/ custom callbacks are beforeSend, error, success. You can take full advantage of this flexible event callback system when authoring custom plugins

Derek Adair
  • 21,846
  • 31
  • 97
  • 134