PHP基础-函数(第14天)
函数
一.什么是函数?
1.1概念
函数:function 是一种语法结构,将实现某个功能的代码块(多行代码)封装到一个结构中,从而实现代码的重复利用(复用)
1.2 语法
函数由以下部分组成:
- function 关键字:声明函数。
- 函数名:标识符,用来调用函数。
- 参数:接收外部传入的数据。
- 形参(形式参数):函数定义时写在括号里。
- 实参(实际参数):函数调用时传入的值。
- 函数体:大括号
{}
内的代码,描述要执行的逻辑。 - 返回值:函数执行后返回的结果(可选)。
基本语法如下:
function 函数名($参数1, $参数2) {// 函数体return $参数1 + $参数2;
}
1.3作用
定义函数的目的是为了实现代码的重复调用,一个功能一个函数(简单明了)
- 代码复用:把常用的功能写成函数,避免复制粘贴。
- 结构清晰:一个功能对应一个函数,逻辑更清楚。
- 易于维护:修改函数内部逻辑,就能统一更新所有调用的地方。
- 提高效率:减少重复劳动,让代码更简洁、可读性更好。
1.4 函数执行的内存分析
1、读取代码进入到代码段(编译:将代码编成字节码储存到内存)
2、根据代码逐行执行
以上原因:编译和执行是分开的(先编译后执行)
函数在执行过程中,PHP 会经历以下几个阶段:
- 函数定义阶段
- 当 PHP 解析到
function
关键字时,会在**函数表(function table)**里登记函数名和函数体,但不会立刻执行函数。 - 只有在调用时才会真正运行函数体。
- 当 PHP 解析到
- 调用阶段
- 调用函数时,PHP 会在**栈内存(stack)**中开辟一个新的“活动记录”(执行上下文)。
- 形参会在这个新空间中分配内存,并用实参的值进行初始化。
- 执行阶段
- 执行函数体中的代码。
- 如果有
return
,返回值会送回到调用点,同时释放函数在栈中使用的内存。 - 如果没有
return
,函数默认返回NULL
。
- 销毁阶段
- 函数执行完毕后,其局部变量、形参等都会随调用栈帧一起销毁,不会影响外部变量(除非用
global
或引用传递)。
- 函数执行完毕后,其局部变量、形参等都会随调用栈帧一起销毁,不会影响外部变量(除非用
1.5函数命名规范
命名规范:由字母,数字下划线组成,但是不能以数字开头
函数作为一种常用的结构 ,一般遵循以下规则;
函数通常名字代表着函数的功能,而有些功能会比较复杂,一个单词不足以表示,可能需要多个组合
1、驼峰法
- 除了左边第一个单词以外,后面所有的单词首字母大写:showParentInfo
2、下划线法
- 单词之间通过下划线链接,单词都是小写:show_parent_info
见名知意:函数名应该清楚表达函数功能,例如 getUserName()
而不是 fun1()
。
小写字母+下划线(常见于过程化代码)
- 例如:
get_user_info()
、calculate_sum()
驼峰命名法(CamelCase)(常见于 OOP 风格)
- 例如:
getUserInfo()
、calculateSum()
动词开头:函数一般执行某个动作,所以建议用动词开头。
- 如:
printReport()
、sendEmail()
、validateInput()
。
避免保留字:不要使用 PHP 内置关键字或函数名,例如 list()
、array()
。
统一风格:团队代码最好统一命名规则,避免一会儿下划线、一会儿驼峰。
函数名字:
在一个脚本周期中,不允许出现同名函数(通常在一个系统开发中都不会使用同名函数)
1.6 引用传值与值传递
在 PHP 中,函数参数有两种传递方式:
- 值传递(默认方式)
- 将实参的值复制一份传给形参。
- 在函数内部修改形参,不会影响外部实参。
- 引用传递
- 在形参前加
&
,表示传递的是变量的“引用”(相当于别名)。 - 在函数内部修改形参,会直接影响外部实参。
- 只有变量才能用引用传递,常量或表达式不行。
- 在形参前加
function display($a,&$b){
$a = $a*$a
$b = $b*$b
echo $a,'<br>',$b,'<br/>';
}
$a = 10 ;
$b= 5
display($a,$b) // 100 25
echo '<hr/>,$a, </br/>,$b //10 25 b是引用传值会影响外部传的实参变了 a 是值传值,不影响外部传的实参值 只有变量能用引用传值
1.7 作用域
1.7.1 概念
变量(常量)能够访问的区域
1、变量可以在普通代码中定义(全局空间)
2、变量也可以在函数内部定义(局部空间)
1.7.2分类
PHP中作用域严格来说分为两种:全局作用域 和 局部作用域,但是PHP内部还定义一些严格意义意外的一种,所以总共算是三种:
**1、全局变量:**就是用户普通定义的变量(函数外部定义)
- 所属全局空间,在PHP中只允许在全局空间使用,理论上函数内部不可访问
2、局部变量:就是在函数内部定义的变量
- 所属当前函数空间:在PHP中只允许当前函数自己内部使用
- 函数周期:函数执行结束(函数就是在战区中开辟内存空间运行)
- 所有形参都可以理解为局部变量
**3、超全局变量:**系统定义的变量(预定义变量,$POST $,SERVER等)
-
系统预定义的全局数组:
$_GET
、$_POST
、$_SERVER
、$_SESSION
、$_COOKIE
、$_FILES
、$_REQUEST
、$_ENV
、$_GLOBALS
。 -
所属超全局空间,没有访问限制(函数内外部都可以访问)
-
超全局变量会将全局变量自动纳入到GLOBALS里面,而GLOBALS里面,而GLOBALS里面,而GLOBALS没有作用限制,所以能帮助局部去访问全局变量,但是必须是使用数组方式
1.7.3**global
**
- global 关键字是一种在函数里面定义变量的一种方式
- 如果使用global定义的变量名在外部存在(全局变量),那么系统在函数内部定义的变量直接指向外部全局变量所指向的内存空间(同一个变量)
- 如果使用global定义的变量名在外部不存在(全局变量),那么系统会在全局空间(外部)定义一个与局部变量同名的全局变量。
- 本质形式
- 在函数和内部外部,对一个同名变量(全局和局部)使用同一块内存地址保存数据,从而实现共同拥有
- 在函数内部声明
global $变量名;
可以访问并修改函数外部的全局变量。- 注意只能声明不能声明同时赋值
$x = 10;
function test(){global $x;$x = $x + 5;
}
test();
echo $x; // 15
$GLOBALS
数组
- 一个关联数组,存放了所有全局变量。
- 可以在函数内部通过
$GLOBALS['变量名']
访问外部变量。
$y = 20;
function demo(){$GLOBALS['y'] = $GLOBALS['y'] + 10;
}
demo();
echo $y; // 30
虽然以上方法可以实现局部与全局的互访,但是通常不会这么使用,一般如果会存在特殊使用,也会使用参数的形式访问。(还可以使用常量,define定义的)
二.静态变量
2.1 概念
静态变量:static ,是在函数内部定义的变量,使用static关键字修饰,用来实现跨函数共享数据的变量:函数运行结束所有的局部变量都会清空,如果重新运行一下函数,所有的局部变量又会重新初始化。
2.2 基本语法
function 函数名(){
//定义变量
staic $变量名 = 值;//通常会在定义的时候就直接赋值}
2.3 静态变量的作用
是为了跨函数共享数据(同一个函数被多次调用)
function display()
{//定义变量-局部变量$local = 1;//定义静态变量static $count = 1;echo $local++, $count++, "<br/>";
}
display(); //11
display(); //12
display();//13
静态变量的原理:
系统在进行编译的时候就会对static这一行进行初始化:为静态变量赋值
函数在调用的时候,会自定跳过static关键字这一行
2.4 使用
1、为了统计:当前函数的调用次数(有没有代替方法)
2、为了统筹函数多次调用得到的不同结果(递归思想)
三.什么是可变函数?
3.1概念
可变函数:当前有一个变量所保存的值,刚好是一个函数的名字,那么就可以使用变量+()来充当函数名使用
$变量名 = 'display'
funciton display(){}
$变量名()
3.2 使用
$a = 'display';
function display()
{echo '123';
}
$a();
可变函数在系统使用的过程中还是比较多的,尤其是使用很多系统函数的时候,需要用户在外部定义一个自定义函数,但是需要传入到系统函数内部使用
//定义系统功函数(假设)
fucntion sys_function($arg1,$arg2){
//给指定的函数(第一个参数),求对应的第二个参数值的4次方//为实际用户输入的数值进行处理$arg2 =$arg2+10;
return $arg1($arg2)
}
//定义一个用户函数:求一个数的四次方
function user_function($num){return $num* $num* $num* $num
}
//求10的4次方
sys_function('user_function',10) //将一个用户定义的函数传入给另外一个函数(函数名—)去使用的过程,称之为回调过程,而被传入的函数称为回调函数
四.什么是匿名函数?
4.1 概念
匿名函数:没有名字的函数
4.2基本语法
function(){
//函数体
}
4.3 基本使用
$func = function () {echo 'hello world';
};
$func(); //调用匿名函数 可变函数//查看变量内容
var_dump($func); //object(Closure)
变量保存匿名函数,本质得到的是一个对象(closure)
4.4 闭包
closure,一词来源于一下两者的结合:
-
要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及他们引用的对象没有被释放)
-
自由变量提供绑定的计算环境(作用域)
简单理解:函数内部有一些局部变量(要执行的代码块)在函数执行之后没有被释放,是因为在函数内部还有对应的函数在引用(函数的内部函数:匿名函数)
//闭包函数
function display()
{$name = __FUNCTION__;$innerfunciton = function () use ($name) { //use 就是将外部变量(局部)保留给内部使用(闭包)//函数内部的函数echo $name;};$innerfunciton();
}
display(); //display
证明:函数的局部变量在使用完之后没有被释放
1、使用内部匿名函数
2、匿名函数使用use
3、匿名函数被返回给外部使用