PHP Inner Functions And Closure
Written by Mike James   
Friday, 07 January 2022
Article Index
PHP Inner Functions And Closure
Lifetimes
Object-oriented PHP
Anonymous functions can be local

Anonymous functions can be local

The reason that functions are global is simply that their name is defined at a global level.

In PHP 5.30 and later there is another way to define a function however and in this case its "name" can be global or local.

An anonymous function is simply a function that you assign to a standard variable. The function's lifespan is determined by the variable. When the variable is destroyed so is the function.

That is to define an anonymous function you write something like:

$variable=function(parameters){function body};

The function is anonymous because it doesn't have a function name that identifies it uniquely. Instead you can think of a reference to the function being stored in the variable and this acts as a name for the function. 

For example:

$MyFunction1 = function() {
 echo('MyFunction ');
};

$MyFunction2=$MyFunction1;

$MyFunction1();
$MyFunction2();

Notice that you can use the reference to the anonymous function just as if it was a variable holding a value. In this case we store another reference to the anonymous function in MyFunction2. You can now call the function using either variable - the function doesn't have a fixed "name".  

What this means is that now an inner anonymous function, stored in a local variable is indeed local.

For example

function MyFunction(){
 echo("My Function");
 $MyInnerFunction=function()
 {
   echo('MyInnerFunction ');
 };
}

This defines an inner anonymous function and you can call the function usng the variable as:

$MyInnerFunction();

Notice that as the variable is local you cannot call the function from any other context than the outer function. Also as soon as MyFunction finishes the local variable is destroyed and the inner anonymous function effectively no longer exists. 

The good news is that not only is the anonymous function local to the containing function it is also subject to closure in that it can access the containing functions variables even if the containing function no longer exists.


morephpRound

Closure

Unlike other languages where closures are automatically created in PHP you have to specify the variable that will be preserved and accessible to the anonymous function with the use construct. 

For example, if you try:

function MyFunction() {
 echo("My Function");
 $mylocalvar="testing";
 $MyInnerFunction = function() {
  echo($mylocalvar);
 };
 $MyInnerFunction();
}

MyFunction();

You will discover that $MyInnerFunction has no access to $mylocalvar. Even an anonymous function doesn't have access to the local variables of the function that contains it.

However you can give it access to any variables in the containing function using the use construct:

function MyFunction() {
 echo("My Function");
 $mylocalvar="testing";
 $MyInnerFunction = function() use( $mylocalvar ) {
 echo($mylocalvar);
};

$MyInnerFunction();
}

Now when you run the program you will see that the inner function does have access to $mylocalvar. It looks a lot like an extra parameter involved in the function call and indeed it is.

Notice that anonymous functions allow you do to things like pass a function as a parameter and return a function as a result. 

For example:

function MyFunction() {
 echo("My Function");
 $mylocalvar="testing";
 $MyInnerFunction = function() use( $mylocalvar ) {
  echo($mylocalvar);
 };

 return $MyInnerFunction;
}

$MyInnerFuncton=MyFunction();
$MyInnerFuncton();

Notice that now the inner function is returned as the result of MyFunction. You can call MyFunction and store the reference to the inner function in a variable. You can then call the inner function even though the outer function is complete and none of its local variables exist any more. The inner function still has access to the variables that you listed in the use construct.

There are two points to consider here.

The first is that closures aren't as useful in a server side language as they are in a client side language. The reason is simply that closures are useful in callbacks and event handling and server side PHP uses far fewer of both.

The second problem is that $this still isn't treated properly by the inner function.  That is you still have to use the $that trick and you still can't access private and protected members.

However anonymous functions do allow you to do a lot of things that would be difficult without them and they are worth knowing about. 

You may not find that inner functions or anonymous functions are something that you want to use but you may have them forced upon you. All you have to do is use a framework when you can write modules of some sort that are imported into other functions or classes and you can discover that any functions you do write are inner functions just as the result of how the framework uses them.

Introduction to PHP

phpcover

Contents

  1. Getting started
    Getting Started With NetBeans PHP - Local Projects
  2. What PHP Does
  3. PHP Variables and Expressions for Complete Beginners
  4. PHP Control Structures 1 - if and else
  5. PHP Control Structures 2 - switch and elseif
  6. PHP loops
  7. Advanced loops
  8. Functions
  9. Ten minutes to PHP objects
  10. PHP Inner Functions And Closure
  11. NetBeans Remote Projects and debugging

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner


PHP Control Structures 1 - if and else

Getting to grips with programming or a new language is a matter of mastering the flow of control. This is the key idea in programming and understanding it makes the difference between a programmer and [ ... ]



Ten Minutes to PHP

Want to get started with PHP but never found the time? Now you can write your first program in around ten minutes and understand where to go next.


Other Articles

espbook

 

Comments




or email your comment to: comments@i-programmer.info

<ASIN:1449392776>

<ASIN:0994346980>

<ASIN:0596006306>

 



Last Updated ( Friday, 07 January 2022 )