
2.8 PHP函数
函数就是可以完成某个工作的代码块,它就像小朋友搭房子用的积木一样,可以反复使用,在使用的时候不用考虑它的内部组成。PHP函数可以分为两类,第一类是内置函数,即PHP自身函数,只需要根据函数名调用即可。PHP备受欢迎的一个原因就是拥有大量的内置函数,包括字符串操作函数和数组操作函数等。例如var_dump()函数就是输出变量的函数。第二类是自定义函数,就是由用户自己定义的、用来实现特定功能的函数。内置函数可以通过查阅PHP开发手册来学习,下面讲解自定义函数。
2.8.1 定义和调用函数

创建函数的基本语法格式为:

上述代码的参数说明如下。
• function:声明自定义函数时必须使用到的关键字。
• fun_name:自定义函数的名称。
• $str1,$str2,…,$strn:函数的参数。
• fun_body:自定义函数的主体,是功能实现部分。
当函数被定义好后就要调用这个函数。调用函数的操作十分简单,只需要引用函数名并赋予正确的参数即可完成函数的调用。
例如,定义了一个函数example(),计算传入的参数的平方,然后连同表达式和结果全部输出。代码如下:

结果如下:

学习笔记
如果定义了一个函数,但是从未调用这个函数,那么这些代码将不会执行。
2.8.2 在函数间传递参数

在调用函数时,有时需要向函数传递参数,参数传递的方式有按值传递、按引用传递和默认参数。
1. 按值传递
按值传递是常用的参数传递方式,将调用者括号内的值依次传递给函数括号内的值。从下面的例子中验证函数接收参数的顺序。代码如下:

运行结果如下:

2. 按引用传递
按引用传递就是将参数的内存地址传递到函数中。这时,在函数内部的所有操作都会影响到调用者参数的值。按引用传递就是传递参数值时在原基础上加&号即可。
下面举例说明按值传递和按引用传递的区别。
• 按值传递:张三和李四是同事,张三有一间独立的办公室,张三给李四提供建筑材料,李四也建造了一个跟张三一模一样的办公室,他们俩在各自的办公室办公,彼此独立。
• 按引用传递:由于公司工费紧张,将李四安排到张三的办公室。二人各有一把钥匙,公用办公室的资源,张三和李四就会相互影响。
例如,下面的代码中,在第一个参数前添加一个&号。

运行结果如下:

从运行结果中可以看出,第一个参数&$parameter1使用引用传递后,函数体内改变$parameter1的值,调用者的参数$number1也相应改变,而$number2和$number3的值则没有改变。
3. 默认参数(可选参数)
还有一种设置参数的方式,即默认参数。可以指定某个参数为默认参数,将默认参数放在参数列表末尾,并且给它指定一个默认值。
例如,使用默认参数实现一个简单的价格计算功能,设置自定义函数values的参数$tax为默认参数,其默认值为空。第一次调用该函数,给参数$tax赋值0.25,输出价格;第二次调用该函数,不给参数$tax赋值,输出价格。代码如下:

结果如下:

学习笔记
当使用默认参数时,默认参数必须放在非默认参数的最右侧,否则函数可能出错。
2.8.3 从函数中返回值

我们已经知道,可以向函数发送信息(参数),不过函数还可以向调用者发回信息。从函数中返回的值称为结果(result)或返回值(return value)。函数将返回值传递给调用者的方式是使用关键字return。return将函数的值返回给函数的调用者,即将程序控制权返回到调用者的作用域。
计算购物车中商品总价
本实例将模拟淘宝购物车功能,并计算购物车中商品总价。购物车中有如下商品信息:
手机单价5000元,购买数量2台;电脑单价8000元,购买数量10台。
操作步骤为:先定义一个函数,将其命名为total,该函数的作用是输入商品的单价和数量,然后计算商品总金额,最后返回商品总金额。代码如下:

上述代码的结果如下:

return语句一次只能返回一个参数,即只能返回一个值,不能一次返回多个值。如果要返回多个值,就要在函数中定义一个数组,将返回值存储在数组中返回。
2.8.4 变量作用域

你可能注意到,有些变量在函数之外,有些变量则在函数之内,它们必须在有效范围内使用,如果变量超出有效范围,则变量也失去意义了。变量的作用域如表2.11所示。
表2.11 变量的作用域

在函数内部定义的变量,其作用域为所在函数,如果在函数外赋值,将被认为是完全不同的另一个变量。在退出声明变量的函数时,该变量及相应的值就会被清除。
比较局部变量和全局变量
比较在函数内赋值的变量(局部变量)和在函数外赋值的变量(全局变量),代码如下:

运行结果如图2.7所示。

图2.7 输出局部变量和全局变量