函数内部的函数。?

时间:2009-10-27 15:19:08

标签: php function

此代码生成结果为56。

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

    return($y+3);
}

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

知道里面会发生什么吗?我很迷惑。

8 个答案:

答案 0 :(得分:91)

X返回(值+3),而Y返回(值* 2)

给定值4,这意味着(4+3) * (4*2) = 7 * 8 = 56

虽然函数的范围不受限制(这意味着您可以安全地“嵌套”函数定义),但这个特定示例容易出错:

1)在致电y()之前,您无法致电x(),因为在y()执行一次之前,实际上不会定义函数x()

2)两次调用x()将导致PHP重新声明函数y(),从而导致致命错误:

  

致命错误:无法重新声明y()

两者的解决方案是分割代码,以便声明两个函数彼此独立:

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

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

这也更具可读性。

答案 1 :(得分:27)

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

请注意,PHP并不真正支持“嵌套函数”,因为仅在父函数的范围内定义。所有功能都是全局定义的。请参阅docs

答案 2 :(得分:16)

不确定该代码的作者想要实现的目标。在另一个函数内定义一个函数并不意味着内部函数只在外部函数中可见。在第一次调用x()之后,y()函数也将在全局范围内。

答案 3 :(得分:7)

这对于没有静态属性,引用等的递归是有用的概念:

function getReqursiveItems($id){
    $allItems = array();

    function getItemms($parent_id){
       return DB::findAll()->where('`parent_id` = $parent_id');
    } 

    foreach(getItems($id) as $item){
         $allItems = array_merge($allItems, getItems($item->id) );
    }

    return $allItems;
}

答案 4 :(得分:5)

可以从另一个函数内部定义一个函数。 在外部函数执行之前,内部函数不存在。

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';

输出

y未定义

y已定义

简单的事情是你不能在执行x之前调用函数y

答案 5 :(得分:3)

您的查询正在进行7 * 8

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

当调用函数x时,会发生创建函数y,它不会运行它。

答案 6 :(得分:0)

如果需要执行某些递归过程(例如,循环真正的多层数组或文件树而无需循环),则函数内的

函数或所谓的嵌套函数非常有用多个循环,或者有时我使用它来避免为需要在多个函数之间划分和隔离功能的小型作业创建类。但是在使用嵌套函数之前,您必须了解这一点

    除非执行主功能,否则
  1. 子功能将不可用
  2. 主函数执行后,子函数将在全局范围内可供访问
  3. 如果您需要调用主函数两次,它将尝试重新定义子函数,这将引发致命错误

这是否意味着您不能使用嵌套函数?不,您可以使用以下解决方法

第一种方法是使用存在函数的条件块将要声明的子函数阻止到全局函数栈中,这样可以防止多次将函数声明到全局函数栈中。

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);

,第二种方法是将child的函数范围限制为local而不是global,为此,您必须将函数定义为 Anonymous 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);

请记住,子对象在主函数或全局函数堆栈之外将不可用

答案 7 :(得分:0)

在嵌套使用第二次函数后,我们收到“重新声明”错误。但是..我们可以这样使用它:

function x( $some_value ){

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

return $nested_function( $some_value );

}