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

Lifetimes

The fact that functions are global means that they don't go out of scope which means that they are never destroyed.

But this doesn't mean that every function has the same lifetime as the program they are contained in.

Any function that you simply declare as part of the program's text can be considered to exist as soon as the program starts running and exist until the program comes to an end. However, PHP is a dynamic interpreted language and this means that it can do things with its own text that other languages can't.

For example you can conditionally declare a function:

if($test) {
 function MyFunction()
 {
  echo("My Function");
 }
}

 

This results in MyFunction not existing within the program until the if statement is executed and the condition is true. Once this has happened the function exists and continues to exist until the end of the program.

You can think of this as

"the function exists from the moment that PHP gets to read about it".

This is a completely general mechanism and applies to any declaration of a function within other PHP code.

Notice that as a function cannot be redefined within PHP this means that any code that declares a function can only be executed once - or you have to make sure that the logic is such that the function isn't created a second time. 

It also applies to inner functions and this means that an inner function doesn't exist until the outer function has been called. This some how seems much stranger than the conditional example given earlier but it really is just the same principle at work.

For example, if you define two functions, one within the other:

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

Then if you simply call MyInnerFunction() it will fail. To make it work you first have to call the outer function and only then does the inner function exist. That is:

MyFunction();
MyInnerFunction();

works but after calling MyFunction once you can't call it again without generating an error.

The solution to the problem of trying to create a function more than once is to make use of the conditional declaration idea. For example:

function MyFunction()
{
 echo("My Function");
 if(!function_exists("MyInnerFunction")){
  function MyInnerFunction()
  {
   echo('MyInnerFunction ');
  }
 }
}

The way that this works should now be obvious. The if statement simply checks to see if the function name exists in the global scope. If it does then the function isn't declared a second time and no error occurs.

You should always enclose inner function declarations within if statements - it makes them safer and it costs very little.

Now we come to a subtle point but one that turns out to have practical import.

Can you call an inner function from within the function that encloses it?

The answer is yes but only after it has been defined. For example; you can't use

function MyFunction()
{
 echo("My Function");
 MyInnerFunction();
 if(!function_exists("MyInnerFunction")){
   function MyInnerFunction()
   {
    echo('MyInnerFunction ');
   }
 }
}

 

Banner

The problem is that when you try to call MyInnerFunction it hasn't been declared yet. However if you move the call to after the if then everything is fine:

function MyFunction()
{
 echo("My Function");
 if(!function_exists("MyInnerFunction")){
   function MyInnerFunction()
   {
    echo('MyInnerFunction ');
   }
 }
 MyInnerFunction();
}

 

This is strange and takes some time to get used to but it is perfectly logical.

Of course the second time MyFunction is called the inner function is already defined and you could in principle call the inner function anywhere you like - as the inner function is global really anywhere you like!

<ASIN:0596006306>

<ASIN:0596101015>

<ASIN:0321442490>

<ASIN:0596005601>

<ASIN:0672329166>

<ASIN:1590598628>



Last Updated ( Friday, 07 January 2022 )