🌴输出函数;时间函数;函数的函数;函数执行;作用于;可变函数;匿名函数和闭包;常用的系统函数…
函数
函数执行的内存分析
函数执行的内存分析:
1. 读取代码进入到代码段(编译:将代码变成字节码存储到内存)
2. 根据代码逐行执行
原因:编译和执行是分开的(先编译后执行)
系统执行函数流程
函数支持默认值 - 类似于 Kotlin
$num1 = 10;
//add($num1,20); //传入的实参,可以是变量或者其他有值的表达式(变量、常量、运算符计算结果)
//函数的默认值
function jian($num1 = 0,$num2 = 0){ //当前的$num1是形参,在编译时不执行,即便执行也是在jian函数内部,不会与外部的$num1变量冲突
echo $num1 - $num2;
}
//调用:默认值如果存在,可以不用传入
jian($num1);
echo '<br>';
echo $num1;
注意事项:
1 .默认值的定义是放在最右边的(多个),不能左边形参有默认值,但是右边没有
- 函数外部定义的变量名字与函数定义的形参名字冲突(同名)是没有任何关联关系的;如果多个函数使用同样的形参名字也不冲突。
引用传值(&$b)
👉 &$b
在调用的时候,必须给引用传值的参数位置传入实际参数,而且参数本身必须是变量。(变量才有指向的数据的内存地址)
//引用传值
function display($a,&$b){
//修改形参的值
$a = $a * $a;
$b = $b * $b;
echo $a,'<br>',$b,'<br/>';
}
//定义变量
$a = 10;
$b = 5;
//调用函数
display($a,$b);
echo '<hr/>',$a,'<br/>',$b;
运行结果:
100
25
---------------------------------------------
10
25
说明:函数在定义的时候,对应的b采用的是取地址,所以在实参传入之后,系统b取到了外部变量b的内存地址, 而a取的是值因此改变之后:a只改变了函数内部自己;b改变自己的同时也改变了外部。
引用传值注意事项:在传入实参的时候,必须传入变量。
//错误调用:引用传值直接传入数据本身而不是变量,因为只有变量能够引用传递🐖
display(10,5); // Fatal error: Only variables can be passed by reference
函数返回值
返回值:return,指的是将函数实现的结果,通过return关键字,返回给函数外部(函数调用处): 在PHP中所有的函数都有返回值。(如果没有明确 return 使用,那么系统默认返回 NULL )
注意:函数的返回值可以是任意数据类型。
function display(){
//输出
echo __FUNCTION__; //输出当前函数名字
}
var_dump(display());
结果:
displayNULL
作用域(不同于Java)
在PHP中作用域严格来说分为两种:但是PHP内部还定义一些在严格意义之外的一种,所以总共算三种:
全局变量:就是用户普通定义的变量(函数外部定义)👉不同于Java
所属全局空间:在PHP中只允许在全局空间使用:理论上函数内部不可调用
脚本周期:直到脚本运行结束(最后一行代码执行完)
🌰
//默认的代码空间:全局空间
$global = 'global area'; //最终会被系统纳入到超全局变量中:$GLOBALS['global'] = global area;
//局部变量(函数内部定义)
function display(){
//所有的形参都可以理解为局部变量
$inner = __FUNCTION__; //局部变量
//访问全局变量
echo $global; //不能访问
}
//调用函数
display();
结果:
Notice: Undefined variable: global in C:\fastwork\Apache24\htdocs\test.php on line 11
display
局部变量:就是在函数内部定义的变量
特效与Java相同
所属当前函数空间:在PHP中只允许在当前函数自己内部使用
函数周期:函数执行结束(函数是在栈区中开辟独立内存空间运行)
超全局变量
超全局变量:系统定义的变量(预定义变量:$_SERVER
、$_POST
等)
所属超全局空间:没有访问限制(函数内外都可以访问)
超全局变量会将 "全局变量" 自动纳入到$GLOBALS里面,而$GLOBALS没有作用域限制,
所以能够帮助局部去访问全局变量:但是必须使用数组方式
🌰
//把上面的输出方式稍加改动
//访问全局变量
echo $global; //不能访问
👇
echo $GLOBALS['global'];
如果想函数内部使用外部变量:除了$GLOBALS之外,通过参数传值(如果要统一战线还可以使用引用传值)。
global 关键字
本质的形式:在函数的内部和外部,对一个同名变量(全局和局部)使用同一块内存地址保存数据,从而实现共同拥有。
基本语法:
global 变量名; //不能赋值
变量名 = 值; //修改
//默认的代码空间:全局空间
$global = 'global area'; //最终会被系统纳入到超全局变量中:$GLOBALS['global'] = global area;
function display(){
$inner = __FUNCTION__;
//定义变量:使用全局变量
global $global; //全局空间存在
echo $global;
//定义变量:全局不存在
global $local;
$local = 'inner';
}
//调用函数 👉 1.函数访问全局变量
display();
//👉2.全局空间访问局部变量
//echo $inner; //不能访问
//访问“局部”变量
echo $local; //可以访问
虽然以上方式可以实现局部与全局的互访,但是通常不会这么用。 一般如果会存在特殊使用,也会使用参数的形式来访问。(还可以使用常量:define定义的)
函数内静态变量(static)
静态变量:static,是在**函数内部** 定义的变量,使用static关键字修饰,
用来实现跨函数共享数据的变量:函数运行结束所有局部变量都会清空,如果重新运行一下函数,
所有的局部变量又会重新初始化。
基本语法:
Function 函数名(){
//定义变量
static $变量名 = 值; //通常会在定义的时候就直接赋值
}
//定义函数
function display(){
//定义变量
$local = 1; //局部变量
//定义静态变量
static $count = 1; //静态变量
echo $local++,$count++,'<br/>';
}
//调用
display();
display();
display();
🍎
11
12
13
静态变量的作用是为了跨函数共享数据(同一个函数被多次调用)
🌴静态变量原理: 系统在进行编译时候就会对static这一行进行初始化,并默认赋值为空值(0,””); 函数在调用的时候,会自动跳过static关键字这一行。
默认赋值为空值(0,””),会自动判段类型,验证 (☄⊙ω⊙)☄
function display(){
$local = 1;
//定义静态变量
static $count ; //静态变量
var_dump(empty($count));
echo $local++,$count++,'<br/>';
}
//调用
display();
display();
display();
🍎
bool(true) 1
bool(false) 11
bool(false) 12
思考:静态变量的使用:
- 为了统计:当前函数被调用的次数(有没有替代方法?)
- 为了统筹函数多次调用得到的不同结果(递归思想)
可变函数
可变函数:当前有一个变量所保存到值,刚好是一个函数的名字,那么就可以使用变量+()来充当函数名使用。
function display(){
echo 'line number '.__LINE__, '<br>fun name is '.__FUNCTION__;
}
$a = 'display';
//可变函数
$a();
可变函数在系统使用的过程中还是比较多的,尤其是使用很多系统函数的时候: 需要用户在外部定义一个自定义函数,但是是需要传入到系统函数内部使用。
✨将一个用户定义的函数传入给另外一个函数(函数名)去使用的过程,称之为回调过程,而被传入的函数称之为回调函数。
//定义系统函数(假设)
function sys_function($arg1,$arg2){
//给指定的函数(第一个参数),求对应的第二个参数值的4次方
//为实际用户输入的数值进行处理
$arg2 = $arg2 + 10;
return $arg1($arg2); //user_function(20)
}
//定义一个用户函数:求一个数的四次方👉回调函数
function user_function($num){
return $num * $num * $num * $num;
}
//求10的4次方
echo sys_function('user_function',10);
匿名函数和闭包
变量保存匿名函数,本质得到的是一个对象(Closure)👉var_dump($func);
//定义基本匿名函数
$func = function(){
echo 'hello world'.'<br>';//函数体
};
//调用匿名函数:可变函数
$func();
//查看变量内容
var_dump($func);
结果
hello world
object(Closure)#1 (0) { }
闭包
闭包:closure, 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中, 这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)
简单理解:函数内部有一些局部变量(要执行的代码块)在函数执行之后没有被释放, 是因为在函数内部还有对应的函数在引用(函数的内部函数:匿名函数)
证明:函数的局部变量在函数使用完之后没有被释放?
1、 使用内部匿名函数;
2、 匿名函数使用局部变量:use 关键字;
3、 匿名函数被返回给外部使用;
验证👇
//闭包函数
function display1(){
//定义变量:局部变量
$name = __FUNCTION__;
//定义匿名函数
$innerfunction = function() use($name){ //use就是将外部变量(局部)保留给内部使用(闭包)
//函数内部的函数
echo $name;
};
//返回内部匿名函数
return $innerfunction;
}
$closure = display1();
//程序运行到此行:display1 函数运行结束:理论上局部变量 $name 应该已经被释放
$closure();
伪类型
伪类型:假类型,实际上在PHP中不存在的类型。但是通过伪类型可以帮助程序员去更好的查看操作手册从而更方便学习。
伪类型主要有两种:在三大类八小类之外
Mixed:混合的,可以是多种PHP中的数据类型
Number:数值的,可以是任意数值类型(整形和浮点型)
常用的系统函数
1.有关输出的函数
print():类似于echo输出提供的内容,本质是一种结构(不是函数),返回1,可以不需要使用括号
print_r():类似于var_dump,但是比var_dump简单,不会输出数据的类型,只会输出值(数组打印使用比较多)
//输出相关
echo print('hello world<br/>');
echo '<hr/>';
print 'hello world<br/>';
echo '<hr/>';
$a = 'hello world<br/>';
print_r($a);
var_dump($a);
🍎
hello world
1
----------------------------
hello world
----------------------------
hello world
string(16) "hello world
"
echo print(‘hello world
’);的输出结果为 : hello world👉换行👉1
2.有关时间的函数
date():按照指定格式对对应的时间戳(从1970年格林威治时间开始计算的秒数), 如果没有指定特定的时间戳,那么就是默认解释当前时间戳
time():获取当前时间对应的时间戳
microtime():获取微秒级别的时间
strtotime():按照规定格式的字符串转换成时间戳
echo date('Y 年 m 月 d 日 H:i:s',12345678),'<br/>';
echo time(),'<br>';
echo microtime(),'<br>';
echo strtotime('tomorrow 10 hours');
对应的输出结果为
1970 年 05 月 24 日 05:21:18
1570690459
0.61865800 1570690459
1570759200
3.有关数学的函数
max():指定参数中最大的值
min():比较两个数中较小的值
rand():得到一个随机数,指定区间的随机整数
mt_rand():与rand一样,只是底层结构不一样,效率比rand高(建议使用)
round():四舍五入
ceil():向上取整
floor():向下取整
pow():求指定数字的指定指数次结果:pow(2,8) == 2^8 == 256
abs():绝对值
sqrt():求平方根
🍎
echo max(2,3); // 3
有关函数的函数
function_exists():判断指定的函数名字是否在内存中存在(帮助用户不去使用一个不存在的函数,让代码安全性更高)
func_get_arg():在自定义函数中去获取指定数值对应的参数
func_get_args():在自定义函数中获取所有的参数(数组)
func_num_args():获取当前自定义函数的参数数量
func_get_args 和 func_num_args 都是统计的对应实参的数量🌴
//函数相关函数
function test($a,$b){
//获取指定参数
var_dump(func_get_arg(1));
echo '<br>';
//获取所有参数
var_dump(func_get_args());
echo '<br>';
//获取参数数量
var_dump(func_num_args());
}
//调用函数
function_exists('test') && test(1,'abs',3,4);
🍎
string(3) "abs"
array(4) { [0]=> int(1) [1]=> string(3) "abs" [2]=> int(3) [3]=> int(4) }
int(4)