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的函数嵌套是以栈的形式实现的。对于每个函数都会分配一段内存来存储函数局部的内容。

php 函数的嵌套的更多相关文章

  1. python中函数的定义,调用,全局变量,局部变量,函数的嵌套使用-初级篇

    函数的基本概述 在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上到下实现功能,可以思考一下如果有某个功能的代码是在多个地方使用的是否可以只写一次?此时的代码该如何定义.先观察以下的案例: ...

  2. Python入门之函数的嵌套/名称空间/作用域/函数对象/闭包函数

    本篇目录: 一.函数嵌套 二.函数名称空间与作用域 三.函数对象 四.闭包函数 ============================================================ ...

  3. Python基础--函数的嵌套和闭包

    一.名称空间和作用域 名称空间:Python所有有关命名的操作都是在操作名称空间,例如变量名,函数名 1.内置名称空间:Python解释器提供好的功能,解释器启动跟着一起启动,是全局作用域 2.全局名 ...

  4. day12(表达式,推导式,名称空间与作用域,函数的嵌套定义)

    一,复习 # 字符串的比较 # -- 按照从左往右比较每一个字符,通过字符对应的ascll进行比较 # print('a' > 'A') #True # print('ac' > 'ab' ...

  5. python第十三天,函数的嵌套定义,global,nonlocal关键字的使用,闭包及闭包的运算场景,装饰器

    今日内容 1. 函数的嵌套定义 2.global,nonlocal关键字 3.闭包及闭包的运用场景 4.装饰器 函数的嵌套定义 1. 概念:在一个函数内部定义另一个函数 2 .为什么要有函数的嵌套定义 ...

  6. python第十二天, 三元表达式, 函数对象,名称空间与作用域,函数的嵌套定义

    复习 1. 字符串的比较: 2. 函数的参数:形参与实参 3. 实参的分类:位置实参与关键字实参 4. 形参分类: 1.无值位置形参 2.有值位置形参 3.可变长位置形参 4.有无值关键字形参 5.可 ...

  7. python13 1.函数的嵌套定义 2.global、nonlocal关键字 3.闭包及闭包的运用场景 4.装饰器

    ## 复习   '''1.函数对象:函数名 => 存放的是函数的内存地址1)函数名 - 找到的是函数的内存地址2)函数名() - 调用函数 => 函数的返回值  eg:fn()() =&g ...

  8. python12--字符串的比较 函数的默认值的细节 三元表达式 函数对象 名称空间 作用域 列表与字典的推导式 四则运算 函数的嵌套

     复习   1.字符串的比较; 2.函数的参数; ******实参与形参的分类: 3.函数的嵌套调用:     # 字符串的比较#  -- 按照从左往右比较每一个字符,通过字符对应的ascii进行比较 ...

  9. python—day9 函数的定义、操作使用方法、函数的分类、函数的嵌套调用

    一.函数的定义 函数的四个组成部分: 函数名. 函数体. 函数返回值. 函数参数 1.概念:重复利用的工具,可以完成特定功能的代码块,函数是存放代码块的容器 2.定义: def:声明函数的关键词 函数 ...

  10. day13函数的嵌套定义,global、nonlocal关键字,闭包及闭包的运用场景,装饰器

    复习 ''' 1.函数对象:函数名 => 存放的是函数的内存地址 1)函数名 - 找到的是函数的内存地址 2)函数名() - 调用函数 => 函数的返回值 eg:fn()() => ...

随机推荐

  1. RPC 简单小试

    由于经常被抓取文章内容,在此附上博客文章网址:,偶尔会更新某些出错的数据或文字,建议到我博客地址 :  --> 点击这里 RPC是指远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器 ...

  2. “全栈2019”Java多线程第十章:Thread.State线程状态详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  3. Usboot V1.68版本

    V1.68版本,我的收藏之一 官方的介绍: 市面上现在大多数U盘都支持启动机器的功能,但是要制作启动型U盘,需要进入WIN98,现在很多人机器 上都没有98了吧,呵呵.为了做个启动盘,装一个98,多冤 ...

  4. angular核心原理解析3:指令的执行过程

    指令的执行过程分析. 我们知道指令的执行分两个阶段,一个是compile,一个是link. 我们可以在指令中自定义compile和link. 首先,我们来讲解如何自定义link函数 举个例子: < ...

  5. VMware Workstation 14 pro License Keys

    AC5XK-0ZD4H-088HP-9NQZV-ZG2R4 CG54H-D8D0H-H8DHY-C6X7X-N2KG6 ZC3WK-AFXEK-488JP-A7MQX-XL8YF ZC5XK-A6E0 ...

  6. 永久激活navicat_premium12.0,支持win32和64位

    1.下载软件以及注册机 链接:https://pan.baidu.com/s/1NGc6YLsgMQRQYEwnGSU16Q   提取码:guno 2.根据自己的电脑位数安装对应的软件,傻瓜式安全(注 ...

  7. ubuntu16.04 安装 mysql-level

    ubuntu16.04 安装 mysql-level 1.下载 mysql-level(直接去官网下载rpm包,我的mysql-server是5.7.9.你下载自己对应的就可以了) 下载连接 2.rp ...

  8. STL项目-学校演讲比赛

    // 学校演讲比赛.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并结束. // #include "pch.h" #include < ...

  9. jQuery 获取元素当前位置offset()与position()

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...

  10. LTE:EPC

    User Identifiers - IMSI and GUTI IMSI   A globle id that unique identifies a subscribe.It composed t ...