php 函数的嵌套

  1. /*一定要小心变量作用域*/
  2. function insert_dynamic()
  3. {
  4. function bar()
  5. {
  6. echo "I don‘t exist until insert_dynamic() is called.\n";
  7. }
  8. }
  9. /* 现在还不能调用bar()函数,因为它还不存在 */
  10. insert_dynamic();
  11. /* 现在可以调用bar()函数了,因为insert_dynamic()函数
  12. 的执行使得bar()函数变为已定义的函数 */
  13. bar();

全局和局部要搞清。

扩展

PHP中的函数嵌套层数限制分析

函数嵌套,这个名字有点纠结,也许不太好理解。一个比较常见的函数嵌套特例:递归函数,即函数自己嵌套自己。 一直以为在PHP中不能有太多的函数嵌套,这是因为在以前某些时候不小心用到了递归,在递归的深度达到100时, 即函数嵌套的层数达到100时,程序会报一个 Fatal error。如下示例:

复制代码代码如下:

function rt() { 
static $i; 
echo $i++, ‘<br />‘; 
rt(); 

rt(); 
die();

在我的win7 + php5.3的环境下报错如下: Fatal error:Maximum function nesting level of ‘100′ reached, aborting!

一直以为是PHP本身的限制,直到某一天切换到liunx环境下以命令行的模式运行,发现,程序限入了死循环。 不同的环境下有不同的结果,为什么呢?好吧,我们直接在源码中查找报错信息,发现没有相关内容,直接debug整个执行过程,也没有在win下的报错。 什么原因?再次切换到win下,再次查找,发现在xdebug中看到了报错信息。在xdebug.c文件的1242行开始: 

复制代码代码如下:

XG(level)++; 
if (XG(level) == XG(max_nesting_level)) { 
php_error(E_ERROR, "Maximum function nesting level of ‘%ld‘ reached, 
aborting!", XG(max_nesting_level)); 
}

这表示什么?之前的函数嵌套的层数限制是xdebug扩展加上的,为什么会有这个限制了呢?在xdebug中,xdebug中会记录每次函数调用, 包括嵌套的函数调用,函数调用中的内存,时间等值,这些值在分析程序性能时有大用。如果没有这个限制,当嵌套的层数太多,机器会内存耗尽。 如果这是一台生产环境的服务器,那么就会有部分服务不可用,当然生产环境下是不会添加这个扩展的。但是在多人共用的开发服务器上就可能有这个扩展, 如果因为一个开发人员的程序错误导致机器不可用,从而使所有的开发人员不能工作,我想这也许是添加限制的原因吧。

如果我们需要把这个限制的层数加大,怎么办呢?改源码,重新编译xdebug扩展?不需要,在xdebug的配置项中有一项叫做xdebug.max_nesting_level, 默认情况下,在php.ini中这个配置项是被注释了的,去掉注释,将这个值成你所需要的值,200?不够,那500吧,但是这个值还是不要太大, 如果递归太多,对程序的性能有很大的影响,此时,以栈的形式实现递归或者用循环替换递归会是一个更好的方案, 如:斐波那契数列(Fibonacci)的实现,用循环来实现会更快。

结论:PHP本身的函数嵌套是没有限制的,如果说有限制,也是内存的限制。这是因为PHP的函数嵌套是以栈的形式实现的。对于每个函数都会分配一段内存来存储函数局部的内容。

时间: 2024-10-31 23:18:04

php 函数的嵌套的相关文章

11、函数对象、函数的嵌套、名称空间与作用域

一.函数对象 函数对象,函数是第一类对象,即函数可以当做数据传递 具体特点: 1.可以被引用: 1 def foo(): 2 print('from foo') 3 4 func=foo 5 6 print(foo) 7 print(func) 8 func() 2.可以当作参数传递 1 def foo(): 2 print('from foo') 3 4 def bar(func): 5 print(func) 6 func() 7 8 bar(foo) 3.返回值可以是函数 1 def fo

函数对象+嵌套

#-*-coding:utf-8 -*-'''函数对象:函数是第一类对象,即函数可以当做数据传递 1.可以被引用 2.可以当做参数来传递 3.返回值可以是函数 4.可以当做容器类型的元素'''#1.可以被引用# def foo():# print('from foo')# func=foo# print(foo)# print(func)# func()#2.可以被当做参数传递# def foo():# print('from foo')# def bar(func):# print(func)

第七课 函数的嵌套调用【项目1-4】

第七课 函数的嵌套调用 项目一[k次方之和] 设计程序,计算: 请在下面的程序结构基础上完成设计. [cpp] view plain copy print? #include<stdio.h> int power(int m,int n); //求m的n次方(m^n) int sum_of_power(int k,int n);  //从1^k到n^k的累加和 int main( ) { int k, n; scanf("%d %d", &k, &n); p

函数对象,函数的嵌套,名称空间与作用域,闭包,装饰器,迭代器,内置函数

一,函数对象 函数对象:函数是第一类对象,即函数可以当做数据传递 1,可以被引用 2,可以做参数的传递 3,返回值可以是函数 4,可以当作容器类型的元素 二,函数嵌套 1,函数的嵌套调用 2,函数的嵌套定义 三,名称空间与作用域 名称空间:存放名字的地方叫名称空间,存放这些值与名字的绑定关系 查看内置名称的两种方法: 三种名称空间 1,内置名称空间:随着python解释器的启动而产生 2,全局名称空间:文件的执行会产生全局名称空间,指的是文件级别定义的名字都会放入该空间 3,局部名称空间:调用函

函数对象、函数的嵌套、名称空间、函数的作用域、闭包

函数对象 def foo(): print('foo') 函数可以被赋值f=fooprint(f) #结果是一个内存地址f() #内存地址加()内运行函数 把函数当成参数传递def bar(func): print(func) func() bar(foo) 把函数当成返回值def bar(func): print(func) return func f=bar(foo)f()把函数当做容器类型的元素去用 def add(): print('=============>function add'

Python/函数的嵌套和闭包

Python基础--函数的嵌套和闭包 一.名称空间和作用域 名称空间:Python所有有关命名的操作都是在操作名称空间,例如变量名,函数名 1.内置名称空间:Python解释器提供好的功能,解释器启动跟着一起启动,是全局作用域 2.全局名称空间:Python中顶行写的,不在函数内部定义的,都是全局名称空间,在运行的时候会产生名称空间,是全局作用域 3.局部名称空间:在一个小范围定义,只能当前范围及其子空间内运行,例如在函数内部定义的,是局部作用域 二.函数的嵌套 1.函数的嵌套调用 2.函数的嵌

day10 python学习 函数的嵌套命名空间作用域等

1.三元运算 #1.三元运算 利用已下方法就可以实现一步运算返回a b中大的值 def my_max(a,b): c=0 a=int(input('请输入')) b=int(input('请输入')) # if a>b: # c=a # else: # c=b #或者这样 c = a if a > b else b return c ret=my_max(1,3) print(ret) 2.补充上节差的知识点 形参: #位置参数 #默认参数(关键字参数) #动态参数 *args:接收说有按照位

Day19_名称空间和作用域_函数的嵌套_函数第一类对象的使用_闭包函数

一. 上节课复习 为何要使用函数 解决代码重用问题 统一维护 程序的组织结构清晰,可读性强 定义函数 !!!先定义后使用 def funcname(arg1,arg2,....) #funcname = 函数体 '''描述信息''' 函数体 return value 定义无参函数 定义有参函数 定义空函数 调用函数 语句形式:foo() 表达式形式:foo(1,2) 函数调用作为另外一个函数的参数:print(foo(1,2)) 函数返回值 不写return--->None return 一个值

函数的嵌套和作用域

函数的嵌套定义 ①内部函数可以使用外部函数的变量 作用域链 在内部函数使用变量时,是从小局部到大局部到全局到内置名字的过程中一级一级网上找,找到最近的一个就使用 nonlocal a 声明一个上层局部变量,往上走一级离得最近并且有a 1.对全局无效 2.对局部的最近的一层产生影响 闭包嵌套函数,内部函数调用外部函数的变量 不调用不是闭包是嵌套 def outer() a = 1 def inner(): print(a) outer() 闭包的应用 可以保护变量,保护上一级局部变量中a = 1