php基础——函数
2020-06-29 04:51
453 查看
函数介绍
- 完成某一功能的程序代码集合,称为函数
- 把一段常用的功能代码,封装到一起,做成一个函数,可以提高代码的复用性和可维护性
- get_defined_functions() 返回所有已定义函数的数组
函数定义
- 函数的参数列表可以是多个,并且数据类型可以是任意类型
- 函数内定义的变量是局部变量,只能在函数内使用,与函数外同名变量不冲突
- 函数中要使用全局变量,使用global关键字
function 函数名(形参1,形参2,n){ // 参数可以不写 执行语句; return; // 返回值写不写看需求,如不写默认返回null }
函数运行原理
代码示例
$num1 = 10; $num2 = 10; //此处传参相当于 $n1=$num1; $n2=$num2 传值赋值 function getSum($n1, $n2){ $res = $n1 + $n2; return $res; } $val = getSum($num1, $num2); echo $val;
内存示例
变量作用域
函数中定义的变量是局部的,函数外不生效
代码示例
function test(){ $a = 100; echo $a; } test(); echo $a; // Notice: Undefined variable: a
内存示例
global使用全局变量
函数中要使用全局变量,使用global关键字
global $a
本质上等价于$a = &$GLOBAL['a']
【重要】global $a
表示希望使用全局区的$a
- 如果没有全局变量
$a
,则会先创建全局变量$a=null
var_dump($GLOBALS)
查看所有的全局变量
代码示例
$a = 100; function test(){ // global $a 表示希望使用全局区的$a // 如果没有全局变量$a,则会先创建全局变量 $a=null // global $a 本质上等价于 $a = &$GLOBAL['a'] 引用赋值 global $a; $a = 10; echo $a; } test(); // 10 echo $a; // 10
function test(){ // 如果没有全局变量$a,则会先创建全局变量 $a=null global $a; var_dump($a); } test(); // null var_dump($a); // null
内存示例
流程分析
1.主栈
$a指向100
2.
test(),调用函数,在栈区新开辟一个新的空间新栈1,入新栈1
3.入栈后执行
global $a,即函数内希望使用一个全局变量
$a
- 如果主栈没有
$a
则会先创建全局变量$a
值为null
,然后全局和局部(主栈和新栈)的变量名$a
指向全局区的null
- 如果有则在新栈1创建
$a变量名
指向全局区100
4.
$a = 10,即新栈1中
$a将全局区的100改为10
5.函数没写返回值,默认返回null,函数结束,出新栈1,新栈1销毁,新栈1中的数据和与新栈1相关的箭头也都没有了
7.
echo $a,主栈中的
$a仍指向10,输出10
函数中的静态变量
- 静态变量的特点,只会被初始化一次
- 静态区数据在函数执行完后,不销毁,即使不再有变量指向(这是一个特例),直到整个进程结束才销毁
代码示例
function test(){ $b = 10; static $a = 0; $a++; echo $a; } test(); test(); test();
内存示例
- 第一次调用
test()
,$a
初始化指向静态区0,$a++
,静态数据变为1,调用结束,新栈1销毁,静态区并不销毁 - 第二次调用
test()
,a不再初始化为0,直接找到静态数据1,‘a不再初始化为0,直接找到静态数据1,`a不再初始化为0,直接找到静态数据1,‘a++`,静态数据变为2,调用结束,新栈2销毁,静态区并不销毁 - 第三次调用
test()
,a不再初始化为0,直接找到静态数据2,‘a不再初始化为0,直接找到静态数据2,`a不再初始化为0,直接找到静态数据2,‘a++`,静态数据变为3,调用结束,新栈2销毁,静态区仍不销毁,直到整个进程结束才销毁
函数传参
函数默认参数的值
// $b的默认值为20,如果调用时不填写,以默认值为准,如果填写,以最新的为准 function test($a, $b=20){ echo $a + $b,'<br>'; } test(10); // 30 test(10,1); // 11
传值赋值
函数参数默认通过值传递
// 函数传参默认值传递 $a = $num function test($a){ echo ++$a,'<br>'; } $num = 10; test($num); // 10 echo $num; // 11
引用赋值
可以在形参前加&修改为引用传递
// 函数传参方式修改为引用传递 $a = &$num function test(&$a){ echo ++$a,'<br>'; } $num = 10; test($num); // 11 echo $num; // 11
内存示例
函数传参 – 不定长参数
- func_num_args — 返回传递给函数的参数数量
- func_get_arg — 返回参数列表的某一项
- func_get_args — 返回一个包含函数参数列表的数组
代码示例
函数的参数可以是基本数据类型任意
function fun(){ return 'hello'; } function test(){ $res1 = func_num_args(); $res2 = func_get_arg(1); $res3 = func_get_args(); var_dump($res1,$res2,$res3); } test(1,5,'hi',array(1,2),fun());
练习题
// 传入参数个数不确定,求和 function getSum(){ $arr = func_get_args(); $sum = 0; foreach ($arr as $value){ $sum += $value; } return $sum; } echo getSum(1,2,5); echo getSum(1,-2,5,6);
内部函数
- 函数和类声明是全局有效的,不管是在多深的函数下声明的类或函数
- 函数调用时才会会执行函数内部代码 (调用时才入栈执行)
函数内部可以定义函数,供函数内部使用
function test(){ function fun(){ echo 'hello world'; } // 内部直接调用内部函数 fun(); } test(); // 'hello world'
函数调用时才会会执行函数内部代码
function test(){ function fun(){ echo 'hello world'; } } test(); // 这里调用之后 fun()才被定义 fun(); // 'hello world'
可变函数
- PHP 支持可变函数的概念
- 如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它
- 可变函数可以用来实现包括回调函数,函数表在内的一些用途
function test(){ echo 'hello world'; } $a = 'test'; $a(); // 先解析$a, test(),若有则执行,若没有则报错
函数面试题
写一个函数,接受两个参数
$a $b和一个函数
$fun,要求通过
$fun求$a $b的和
// 新浪面试题:写一个函数,接受两个参数$a $b和一个函数$fun,要求通过$fun求$a $b的和 // 方案一:最容易理解 function test($n1,$n2,$n3){ echo $n3; } function getSum($n1,$n2){ return $n1 + $n2; } $a = 1; $b = 2; test($a, $b, getSum($a, $b)); ============================== // 方案二:使用可变函数知识点 function test($n1,$n2,$n3){ echo $n3($n1,$n2); } function getSum($m1,$m2){ return $m1 + $m2; } $a = 1; $b = 2; $funName = 'getSum'; test($a,$b,$funName); ============================= // 方案三:方案二的改进使用 function test($n1,$n2,$n3){ function getSum($n1,$n2){ return $n1 + $n2; } return $n3($n1,$n2); } $a = 1; $b = 2; $funName = 'getSum'; echo test($a, $b, $funName);
匿名函数
- 匿名函数,也叫闭包函数,允许临时创建一个没有指定名称的函数
- 最经常用作回调函数参数的值
- 闭包函数也可以作为变量的值来使用,最后要加上分号:
- 匿名函数其实是一个对象数据类型
代码示例
$fun1 = function ($n1, $n2){ return $n1 + $n2; }; // 这里是加;的 // 调用匿名函数 echo $fun1(1,3); var_dump($fun1); // object
回调函数
调用某个函数A,而这个函数内又会调用你实现的另一个函数B,那么函数B就是所谓的回调函数
function test($n1,$n2,$n3){ echo $n3($n1,$n2); } function getSum($m1,$m2){ return $m1 + $m2; } $a = 1; $b = 2; $funName = 'getSum'; test($a,$b,$funName);
匿名函数用作回调函数参数的值(开发中用的挺多)
function test($n1, $n2, $n3){ $sum = $n1 + $n2; $res = $n3($sum); // 回调 return $res; } echo test(1, 3, function ($v){return $v*2;}); // 第三个参数为匿名函数
递归函数
- 递归函数即自调用函数,在函数体内部直接或间接的自己调用自己
- 函数体中会附加一个条件判断,以判断是否需要执行递归调用,并且在特定的条件下终止函数的递归
代码示例
function abc($n){ // 此处是传值赋值 if ($n>2){ abc(--$n); // $n = $n-1; abc($n) } echo $n,'<br>'; } abc(4); // 2 2 3 // 思考: 如果是 $n-- 会怎么? 无限递归
内存示例
递归练习1 :1 ~ n的和
function sum($n){ if ($n == 1){ return 1; } return $n+sum($n-1); } echo sum(100);
递归练习2 :斐波那契数列
// 斐波那契数列 1 1 2 3 5 8 13 function test($n){ if ($n == 1 || $n == 2){ return 1; }else{ return test($n-1) + test($n-2); } } $res = test(5); echo $res;
相关文章推荐
- php基础复习函数、类、对象、设计模式....
- PHP循环函数使用介绍之PHP基础入门教程
- PHP基础--strtr和str_replace字符替换函数
- 常用的php基础函数语法
- PHP基础之------函数
- php基础03_函数
- PHP基础系列之字符串——字符串常用函数的分类
- php 安全基础 附录B. 函数
- PHP基础知识总结02(常用的数组函数)
- php语法基础(一)- 变量、常变量、函数、分支和循环、字符串、数组、类、时间、日期、包含文件、文件及图片读写等
- PHP基础之 define() 函数
- PHP和js数组、字符串、函数不同点基础总结
- PHP基础函数总结
- php基础函数
- PHP基础-对数据判断的内置函数集合
- 基础补习:PHP易混淆函数的区分
- 【PHP】基础笔记 09 —— 函数
- php基础语法之函数篇
- php基础知识【函数】(5)正则preg