Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closures in PHP... what, precisely, are they and when would you need to use them?

Tags:

closures

oop

php

So I'm programming along in a nice, up to date, object oriented fashion. I regularly make use of the various aspects of OOP that PHP implements but I am wondering when might I need to use closures. Any experts out there that can shed some light on when it would be useful to implement closures?

like image 496
rg88 Avatar asked Sep 28 '08 21:09

rg88


People also ask

What are closures in PHP?

A closure is an anonymous function that can access variables imported from the outside scope without using any global variables. Theoretically, a closure is a function with some arguments closed (e.g. fixed) by the environment when it is defined. Closures can work around variable scope restrictions in a clean way.

When should closures be used?

Closures are frequently used in JavaScript for object data privacy, in event handlers and callback functions, and in partial applications, currying, and other functional programming patterns.

What is a closure in PHP and why does it use the use identifier?

A closure is a separate namespace, normally, you can not access variables defined outside of this namespace. There comes the use keyword: use allows you to access (use) the succeeding variables inside the closure. use is early binding. That means the variable values are COPIED upon DEFINING the closure.

What are closures used for?

Closures are useful because they let you associate data (the lexical environment) with a function that operates on that data. This has obvious parallels to object-oriented programming, where objects allow you to associate data (the object's properties) with one or more methods.


2 Answers

PHP will support closures natively in 5.3. A closure is good when you want a local function that's only used for some small, specific purpose. The RFC for closures give a good example:

function replace_spaces ($text) {     $replacement = function ($matches) {         return str_replace ($matches[1], ' ', ' ').' ';     };     return preg_replace_callback ('/( +) /', $replacement, $text); } 

This lets you define the replacement function locally inside replace_spaces(), so that it's not:
1) Cluttering up the global namespace
2) Making people three years down the line wonder why there's a function defined globally that's only used inside one other function

It keeps things organized. Notice how the function itself has no name, it simply is defined and assigned as a reference to $replacement.

But remember, you have to wait for PHP 5.3 :)

You can also access variables outside it's scope into a closure using the keyword use. Consider this example.

// Set a multiplier    $multiplier = 3;  // Create a list of numbers    $numbers = array(1,2,3,4);  // Use array_walk to iterate    // through the list and multiply    array_walk($numbers, function($number) use($multiplier){    echo $number * $multiplier;    });  

An excellent explanation is given here What are php lambdas and closures

like image 89
dirtside Avatar answered Oct 06 '22 13:10

dirtside


When you will need a function in the future which performs a task that you have decided upon now.

For example, if you read a config file and one of the parameters tells you that the hash_method for your algorithm is multiply rather than square, you can create a closure that will be used wherever you need to hash something.

The closure can be created in (for example) config_parser(); it creates a function called do_hash_method() using variables local to config_parser() (from the config file). Whenever do_hash_method() is called, it has access to variables in the local scope ofconfig_parser() even though it's not being called in that scope.

A hopefully good hypothetical example:

function config_parser() {     // Do some code here     // $hash_method is in config_parser() local scope     $hash_method = 'multiply';      if ($hashing_enabled)     {         function do_hash_method($var)         {             // $hash_method is from the parent's local scope             if ($hash_method == 'multiply')                 return $var * $var;             else                 return $var ^ $var;         }     } }   function hashme($val) {     // do_hash_method still knows about $hash_method     // even though it's not in the local scope anymore     $val = do_hash_method($val) } 
like image 26
Dan Udey Avatar answered Oct 06 '22 14:10

Dan Udey