风之旅人 Android Dev Engineer

5.PHP函数

2019-10-10
PHP

🌴输出函数;时间函数;函数的函数;函数执行;作用于;可变函数;匿名函数和闭包;常用的系统函数…

函数

函数执行的内存分析

函数执行的内存分析
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 .默认值的定义是放在最右边的(多个),不能左边形参有默认值,但是右边没有

  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

思考:静态变量的使用:

  1. 为了统计:当前函数被调用的次数(有没有替代方法?)
  2. 为了统筹函数多次调用得到的不同结果(递归思想)

可变函数

可变函数:当前有一个变量所保存到值,刚好是一个函数的名字,那么就可以使用变量+()来充当函数名使用。

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);

匿名函数和闭包

视频地址👉https://www.bilibili.com/video/av12863134/?p=68

变量保存匿名函数,本质得到的是一个对象(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.有关时间的函数

👉 https://www.php.net/manual/zh/function.date.php

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)

相关文章

上一篇 4.PHP文件包含

下一篇 6.PHP错误处理

评论