php函数基础

return

  1. 中断文件的功能:终止的仅仅是当前return所在的文件,而不是终止整个程序。
  2. 返回值
  3. return返回结果,可以是一个变量,所以,同样支持值传递和引用传递两种方法,如果使用引用传递,则在函数名的前面加上一个&

exit()/die()

exit()和die()的功能一模一样,他们就是一个功能的两种叫法。作用是终止程序。

sleep()

sleep后面有一个参数,代表程序延迟多少秒后继续执行。

函数调用时间

代码是先进行解析再执行里面的语句,解析阶段已经预先给function开辟了空间,所以执行阶段调用函数时,可以将调用函数放在函数声明之前。

可变函数

可以用一个变量来存放函数名,需要调用函数的时候,直接调用这个变量

作用:将一堆复杂的函数放在一个可变的数组集合中。

1
2
3
4
5
6
7
8
9
10
11
12
13
imagecreatefromjpg();
imagecreatefromjpeg();
imagecreatefrombmp();
imagecreatefromgif();
$file = 'chihuo.jpg';
$type = 'jpg';
$arr = array(
'jpg' => 'imagecreatefromjpg',
'jpeg'=> 'imagecreatefromjpeg',
'bmp' => 'imagecreatefrombmp',
'gif' => 'imagecreatefromgif'
)
$arr[$type]();

匿名函数

没有函数名的函数,称之为匿名函数,匿名函数一般是将他赋值给一个变量,需要加载的时候,直接加载这个变量

作用:调用完成后使用unset快速销毁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
$fn = function($name){
echo $name;
}
var_dump($fn);
``
>在匿名函数中,要先声明函数,在定义函数

### create_function() 创建一个函数
>作用:网站多国语言创建有需求的语言函数,节约空间

语法
:`create_function(‘参数列表’,’函数体’);`
>create_function括号内的参数和函数体,必须要被单引号包裹起来,不能使用双引号
如果要传递多个参数,在参数列表的单引号内,用,进行分割
在一些大型的项目中,使用create_function模式去创建函数,可以极大的节省项目所占用的内存空间

**`create_function`创建函数以后,默认的函数名是(隐藏字节+lambda_1),每当调用一次函数,后面的数字加1,重启apache以后,数字清零**

### function_exists() 判断一个函数是否已经被定义
>一般项目中代码量很大,去寻找一个函数会比较复杂,所以会用function_exists(‘函数名’)去判断一个一个函数是否已经被定义

### 参数
形参: 声名函数时所使用的参数
实参: 调用函数时所使用的参数

**直接传递参数的模式,就是一个值传递的过程,改变一个变量的值,不影响另一个变量**

>如果一个参数,有默认值的话,如果实参没有传递,形参以默认值的数据存在,而如果实参传递了一个数据。则形参以实参传递的数据为主

**参数的默认值不能是一个变量,因为function关键词在代码的解析阶段就会去运行,但是这个时候并没有变量的赋值,变量的赋值操作是在代码的运行阶段才会被复制。**

**参数的默认值,可以是一个常量,如果在调用函数之前定义了这个常量,则默认值会以常量的值进行计算。如果在调用函数之前还没有定义这个常量,则函数会将常量名当成一个普通的字符串去解析。**

我们会把带默认值的形参统一放在参数列表的最右边,这样,在实参传递的时候,就不会出现问题

**参数个数带来的问题**
>实参的个数少于形参的个数---报错--代码还会继续运行下去
形参的个数少于实参的个数--不报错,代码正常运行--超出部分不被接收

### 极限情况

在一个函数不知道会传递多少个实参的时候,一般形参一个不写。代码不会报错。

**func_get_args()**
会将传递的实参以一个数组的形式去进行保存。
**func_get_arg(num)**
获取传递的第num+1个实参的值。
**func_num_args()**
获取传递实参的个数。

// 计算不确定个数数字的和。
//方法一
function hs(){
$num=func_num_args();
$sum=0;
for($i=0;$i<$num;$i++){
$sum+=func_get_arg($i);
}
echo $sum;
}
hs(1,3,5,6,7,8,9);

//方法二
function hs2(){
$arr=func_get_args();
$sum=0;
for($i=0,$n=count($arr);$i<$n;$i++){
$sum+=$arr[$i];
}
echo $sum;
}
hs2(1,3,5,6,7,8,9);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
>我们可以用func_get_args去同时替代func_get_arg,func_num_args两个函数

>如果我需要返回的值是一个非常非常大的数组或者其他数据类型,如果使用值传递,则需要花费时间去重新复制一个值,而如果使用引用传递,直接复制地址就可以了,可以节省很多的时间

### 变量的作用域
#### 全局变量
在函数外部定义的变量称之为全局变量

#### 局部变量
在函数体内部定义的变量称之为局部变量

>在JS中全局变量可以在局部使用,局部变量不能在全局中使用。
在PHP中,全局变量不能再局部使用,局部变量也不能在全局中使用。
PHP中全局变量只能在函数的外面使用,局部变量只能在函数的内部使用

**如果一个变量的作用域同时包含函数内和函数外,那么他就是一个超全局的变量**
九大超全局变量的作用域都是函数内+函数外

##### $GLOBALS

用$GLOBALS去定义一个变量,$变量名和$GLOBAL[‘变量名’]存在一定的关系。
>$变量名和$GLOBALS变量名两者是一个一体的关系,修改一个另一个也会发生变化,删除一个另一个就不存在了

**关键词global**
语法 global 变量名
作用,将一个全局变量引用传值到局部变量中,两者是两个独立的变量

function hs(){
global $age;
$age++;
unset($age);
}
$age = 27;
hs();
echo $age;

结果:28;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
>虽然global被php大力推广,但是效果很差,程序员还是习惯使用$GLOBALS用法

### 变量的生命周期

全局变量的生命周期,是从**被定义的时候开始,到文件运行完毕**以后,当前文件的全局变量生命周期就会结束。

局部变量的生命周期,是从**函数内部被定义开始,到函数执行完毕**以后,当前函数内的所有变量,生命周期就会结束

**static 静态变量**
static 用来定义一个静态变量
>静态变量只会被初始化一次,之后不会被重新初始化
静态变量的生命周期等同与全局变量的生命周期,但是他的作用域等同于局部变量的作用
以上所说都是正常情况下变量的生命周期,但是,我们同样可以用unset()来提前结束一个变量的生命周期。

### 匿名函数
可以通过对变量的类型进行判断,如果是一个字符串,说明是一个可变函数,如果是一个对象,说明是一个匿名函数

匿名函数的优点
>匿名函数可以随时随地被调用,也可以随时随地被销毁。特别适合一些临时性的函数

**use**
虽然,匿名函数是一个赋值语句,但是里面的变量都是一些局部变量。 我们可以利用use将一个和函数处于同一作用域的变量引用进来

$c = 30;
$fn = function() use($c){
$a = 10;
$b = 20;
echo $a+$b+$c;
}

$fn();

结果:60;

1
2


$name = ‘rose’;
function abc(){
$name = ‘jack’;
$fn = function() use($name){
echo $name;
}
$fn();
}
abc();

结果是:jack;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
>作用域并不是一成不变的,一个全局变量,也可能会变成一个局部变量。
use调用函数同样支持值传递和引用传递,如果使用引用传值,在use右边的变量前加上一个&

### 递归函数

递归是属于分治(分,治,合)的算法。迭代也属于分治的算法。
递归函数,就是在一个函数里面继续调用一个函数。

递归函数必须由两个部分组成:
递归点:一个函数继续调用他本身。 如果没有递归点,他就不算一个递归函数。
递归出口:如果一个函数不断地调用他本身,没有出口的话,这个函数会一直运行到空间耗尽或者是时间耗尽的情况才会结束。所以一个函数必须要有递归出口

计算个菲波拉契数列,输出第n项的数字

```php
//计算菲波拉契数列
//用递归实现菲波拉契数列
function fn($n){
//第一项和第二项的结果是1
if($n==1||$n==2){
return 1;
}
//从第三项开始,每一项等于前两项的和
return fn($n-1)+fn($n-2); //递归点
}

echo fn(11);