Function inside a function.?

PhpFunction

Php Problem Overview


This code produces the result as 56.

function x ($y) {
	function y ($z) {
		return ($z*2);
 	}

	return($y+3);
}

$y = 4;
$y = x($y)*y($y);
echo $y;

Any idea what is going inside? I am confused.

Php Solutions


Solution 1 - Php

X returns (value +3), while Y returns (value*2)

Given a value of 4, this means (4+3) * (4*2) = 7 * 8 = 56.

Although functions are not limited in scope (which means that you can safely 'nest' function definitions), this particular example is prone to errors:

  1. You can't call y() before calling x(), because function y() won't actually be defined until x() has executed once.

  2. Calling x() twice will cause PHP to redeclare function y(), leading to a fatal error:

> Fatal error: Cannot redeclare y()

The solution to both would be to split the code, so that both functions are declared independent of each other:

function x ($y) 
{
  return($y+3);
}

function y ($z)
{
  return ($z*2);
}

This is also a lot more readable.

Solution 2 - Php

(4+3)*(4*2) == 56

Note that PHP doesn't really support "nested functions", as in defined only in the scope of the parent function. All functions are defined globally. See the docs.

Solution 3 - Php

Not sure what the author of that code wanted to achieve. Definining a function inside another function does NOT mean that the inner function is only visible inside the outer function. After calling x() the first time, the y() function will be in global scope as well.

Solution 4 - Php

This is useful concept for recursion without static properties , reference etc:

function getRecursiveItems($id){
    $allItems = array();
    
    function getItems($parent_id){
       return DB::findAll()->where('`parent_id` = $parent_id');
    } 
   
    foreach(getItems($id) as $item){
         $allItems = array_merge($allItems, getItems($item->id) );
    }

    return $allItems;
}

Solution 5 - Php

It is possible to define a function from inside another function. the inner function does not exist until the outer function gets executed.

echo function_exists("y") ? 'y is defined\n' : 'y is not defined \n';
$x=x(2);
echo function_exists("y") ? 'y is defined\n' : 'y is not defined \n';

Output

y is not defined

y is defined

Simple thing you can not call function y before executed x

Solution 6 - Php

Your query is doing 7 * 8

x(4) = 4+3 = 7 and y(4) = 4*2 = 8

what happens is when function x is called it creates function y, it does not run it.

Solution 7 - Php

function inside a function or so called nested functions are very usable if you need to do some recursion processes such as looping true multiple layer of array or a file tree without multiple loops or sometimes i use it to avoid creating classes for small jobs which require dividing and isolating functionality among multiple functions. but before you go for nested functions you have to understand that

  1. child function will not be available unless the main function is executed
  2. Once main function got executed the child functions will be globally available to access
  3. if you need to call the main function twice it will try to re define the child function and this will throw a fatal error

so is this mean you cant use nested functions? No, you can with the below workarounds

first method is to block the child function being re declaring into global function stack by using conditional block with function exists, this will prevent the function being declared multiple times into global function stack.

function myfunc($a,$b=5){
	if(!function_exists("child")){
		function child($x,$c){
			return $c+$x;	
		}
	}
	
	try{
		return child($a,$b);
	}catch(Exception $e){
		throw $e;
	}
	
}

//once you have invoke the main function you will be able to call the child function
echo myfunc(10,20)+child(10,10);

and the second method will be limiting the function scope of child to local instead of global, to do that you have to define the function as a Anonymous function and assign it to a local variable, then the function will only be available in local scope and will re declared and invokes every time you call the main function.

function myfunc($a,$b=5){
	$child = function ($x,$c){
		return $c+$x;	
	};
	
	try{
		return $child($a,$b);
	}catch(Exception $e){
		throw $e;
	}
	
}

echo myfunc(10,20);

remember the child will not be available outside the main function or global function stack

Solution 8 - Php

After using second time function with nested we get "redeclare" error. But.. We can use this like that:

function x( $some_value ){

$nested_function = function($x){ return $x*2; };

return $nested_function( $some_value );

}


Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPostoView Question on Stackoverflow
Solution 1 - PhpDurothView Answer on Stackoverflow
Solution 2 - PhpLukáš LalinskýView Answer on Stackoverflow
Solution 3 - PhpAnti VeerannaView Answer on Stackoverflow
Solution 4 - Phpd.raevView Answer on Stackoverflow
Solution 5 - PhpNanhe KumarView Answer on Stackoverflow
Solution 6 - PhpMike ValstarView Answer on Stackoverflow
Solution 7 - PhpAylian CraspaView Answer on Stackoverflow
Solution 8 - Php0arkcodeView Answer on Stackoverflow