函数就是有一定功能的一些语句组织在一起的一种形式。那么在PHP中一种是系统内置的函数,或者是PHP扩展模块一起编译的,例如使用mysqli_connect()函数,就需要在编译PHP的时候有mysql的支持。你可以根据phpinfo()内置函数得知php加载了哪些扩展库。另一种就是用户根据自己需求进行定义函数,可以实现独立的程序代码段。
目录
【1】定义函数
【2】函数的参数
【3】引用传参的函数
【4】默认参数的函数
【5】可变个数参数的函数
【6】可变函数
【7】回调函数
【8】递归函数
【9】匿名函数
【10】自定义函数库
function 函数名([参数1,参数2,...,参数n]) # 函数头 function关键字
{ #函数体开始花括号
函数体; #任何有效的PHP代码都可以作为函数体的使用
return 返回值; #可以从函数中返回一个值
} #函数体结束花括号
每个自定义函数都必须使用"function"关键字进行声明
函数名命名和PHP 中的其它标识符命名规则相同。有效的函数名以字母或下划线打头,后面跟字母,数字或下划线。注意:php函数名不区分大小写,但是最好定义和调用使用相同的大小写。
函数名后面的圆括号也是必要的,括号里面表明一组可以接收的参数列表,用逗号隔开,当然也可以没有参数。函数名后面的是形参,调用时候传入的叫做实参。
函数体就是在花括号里面,函数被调用的时候,首先执行执行函数体第一行,遇到return语句或者结束的花括号,执行完毕。其中函数体里面可以是任何有效的PHP代码,甚至是类或其他函数。
函数无需在调用之前被定义(不同与c语言,需要先声明),除非它还不存在。PHP函数具有全局性。
PHP函数不能重载,不能定义重名的函数,也不能和系统函数重名,也不能取消定义。
函数的返回值return语句可以向函数调用者返回函数体中任意确定的值,然后程序控制权返回到调用者的作用域处,也即是退出函数。如果函数执行到return语句,那么后面的语句将不被执行。任意类型都能返回,但是只能返回一个值。如果省略不写return,则返回null。
只有在调用函数的时候,函数中的语句才会被执行。
函数是结构化编程,注重程序的功能,因此在编写函数前,要先确定程序要执行的所有具体任务,包括参数,作用,返回值。
echo cube(2);//此处调用全局函数cube传入参数2然后将返回值echo出来。
/*
函数名:cube 作用 :求一个数的三次方
参数: $var 一个数值
返回值:返回一个数的三次方
*/
function cube($var){
return $var*$var*$var;
}
PHP是弱语言类型,不需要去指名变量的类型。这也是一大优点,所以在php中没有函数重载的概念。通过参数列表可以传递信息到函数,即以逗号作为分隔符的表达式列表。参数是从左向右求值的,因此调用的时候要对应形参的位置。
function intro($name,$age){//定义函数圆括号里面是形参
echo 'My name is ',$name,'and age is ',$age;
}
intro('tacks',20);//调用函数圆括号里面是实参
默认情况下,函数参数通过值传递(因而即使在函数内部改变参数的值,它并不会改变函数外部的值)。如果希望允许函数修改它的参数值,必须通过引用传递参数。如果想要函数的一个参数总是通过引用传递,可以在函数定义中该参数的前面加上符号 &。注意引用传值传的是变量,变量地址,不是具体的某个值。
function quote(&$num){
$num += 100;
$num = 'old num + 100 ='.$num.'
';
return $num;
}
//quote(10);// Fatal error: Only variables can be passed by reference
//quote($a=10);//Strict standards: Only variables should be passed by reference
echo quote($a);#传入一个未定义的变量$a,没有报错,函数引用传值经过执行后把结果返回给$a
echo $a;
//上面输出两行 old num + 100 =100
echo '
';
$a = 10;#重新赋值$a
echo quote($a);#传入一个变量$a,把$a引用传值到函数体内进行执行,返回给$a
echo $a;
//上面的输出两行 old num + 100 =110
在定义函数的时候声明了参数,但是在调用的时候,没有指定参数或是少了指定参数,就会出现缺少参数的警告。在PHP中,支持函数的默认方式调用,即为参数指定一个默认值。也就是在调用函数时候,如果没有传入指定参数的值,在函数中会使用参数的默认值。默认值必须是常量表达式,不能是变量,类成员或者函数调用。
//默认传参
function person($name='tacks',$age=20,$sex='man'){
echo 'My name is ',$name,' and age is ',$age,' and sex is ',$sex,'
';
}
person();//都按照默认值输出
person('Jay Chou',40);//$name=Jay Chou $age=40 $sex按照默认值输出
person(22);//$name=22 $age $sex按照默认值输出。我原本就是想改变默认age的年龄
person($age=22);//和上面22情况一样。如果你想使用默认值,那么默认值一定要放在右侧
当调用函数传递参数的时候,实参和形参是按照顺序对应传递数据的,如果实参的个数少于形参,那么最右边的形参不会被传值。也就是说,当使用默认参数时,任何默认参数必须放在任何非默认参数的右侧。否则可能不会按照预期的执行。
默认值也可以是数组和特殊类型null。
function foo($number,$names=['tacks','Bruce Lee'],$say=null){
$say = is_null($say)?"I am cool":$say;
echo $number.':'.join(" and ",$names)." say ".$say.'
';
}
foo(1);
foo(2,['Jay Chou','JJ Lin'],'We can sing very well');
/*输出
1:tacks and Bruce Lee say I am cool
2:Jay Chou and JJ Lin say We can sing very well
*/
上面的默认参数适合实参个数少于形参的情况。而实参多于形参的话可以用可变参数列表。也就是如果系统函数可以接任意数量的参数,则需要在函数中使用PHP系统提供的func_get_args()函数获取参数列表,用func_num_args()获取参数个数。
function more(){
$args = func_get_args();//将所有传入函数内的参数当作一个数组返回
$count= func_num_args();//获取传入参数的个数
for($i=0;$i<$count;$i++){
echo "Parameter ",$i," is ",$args[$i],'
';
}
}
more(1,'a','one','yi');//可以输出各个参数的值
PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数不能用于例如 echo,print,unset(),isset(),empty(),include,require 以及类似的语言结构,需要使用自己的包装函数来将这些结构用作可变函数。
function foo(){
echo 'this is foo()'.'
';
}
$func = 'foo';//把函数名赋值给变量,再用变量加()的形式调用
$func();//this is foo()
//使用 echo 的包装函数
function echoit($string){
echo $string.'
';
}
$func = 'echoit';
$func('echoit'); // echoit
class Foo{
function Variable(){
$name = 'Bar';
$this->$name();//这里会调用到bar方法
}
function Bar(){
echo 'This is Bar';
}
}
$obj = new Foo();
$func = 'Variable';
$obj->$func();//这里也可以调用对象的Variable方法
如果要是自定义一个可以回调函数,可以使用变量函数来实现。也就是callback类型的参数。所谓回调函数并不是传递一个标准的变量,而是将另一个函数名,作为参数传递到调用的函数中。
为什么要使用会有回调函数?我们知道通过参数的传递可以改变调用函数的执行行为。但是仅仅可以将一个值传递给函数能力还是有限的,如果可以将用户自定义的一个执行过程传递到函数中,那就可以大大增加用户对函数的扩展功能。
function filter($fun){
for($i=0;$i<=100;$i++){
if($fun($i))
continue;
echo $i,'
';
}
}
/*
自定义条件函数one($num) 过滤掉参数是3的倍数的
作用:如果是参数为3的倍数,那么就返回true,否则返回false
$param int $num 传一个整数作为参数
*/
function one($num){
return $num%3 == 0;//使用比较运算符返回结果
}
/*
自定义条件函数two($num) 过滤掉回文的字符
作用:如果是参数是一个回文数,那么就返回true,否则返回false
$param int $num 传一个整数作为参数
*/
function two($num){
return $num == strrev($num);//strrev反转字符串
}
//可以通过编写不同的过滤规则 来实现filter,增强了filter函数的功能
filter('one');
echo '
';
filter('two');
使用call_user_func()与call_user_func_array()回调函数定义回调
这两个函数作用一样,只是用法,第一个参数都是回调函数名,前者是使用参数列表,后者使用的数组来存放参数。
call_user_func — 把第一个参数作为回调函数调用
call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] ) : mixed
call_user_func_array — 调用回调函数,并把一个数组参数作为回调函数的参数
call_user_func_array ( callable $callback , array $param_arr ) : mixed
function filter($fun){
for($i=0;$i<=100;$i++){
//if($fun($i))//将原本利用变量函数 改成下面的
if(call_user_func_array($fun,[$i]))
continue;
echo $i,'
';
}
}
类静态函数和对象方法的回调
call_user_func_array([类名,静态方法名],[参数]);//回调类静态方法
call_user_func_array([对象,方法],[参数]);//回调对象方法
class Demo{
static function fun($msg1,$msg2){
echo '$msg1 ='.$msg1,' $msg2 ='.$msg2,'
';
}
}
call_user_func_array(['Demo','fun'],['Tacks','20']);//回调类静态方法
class Test{
function fun($msg1,$msg2){
echo '$msg1 ='.$msg1,' $msg2 ='.$msg2,'
';
}
}
call_user_func_array([new Test,'fun'],['Nine','9']);//回调对象方法
递归函数即自己调用自己。通常函数体内要附加一个条件进行判断是否需要递归调用,并且在特定条件下会终止函数的递归调用,然后把流程的主控权交回到上一层函数执行。递归函数最大的好处在于可以精简程序的繁杂和重复调用程序。
function recursion($n){
echo $n,' ';
if($n>0)
recursion($n-1);
else
echo '<-->';#在$n=0的时候输出,然后开始向外层执行
echo $n,' ';
}
recursion(9);//9 8 7 6 5 4 3 2 1 0 <-->0 1 2 3 4 5 6 7 8 9
匿名函数(Anonymous functions),也叫闭包函数(closures),允许临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。当然,也有其它应用的情况。匿名函数目前是通过 Closure 类来实现的。
$fun = function($param){ #将一个没有名字的函数赋给变量$fun
echo $param;
};# 这里记得加分号
$fun('Tacks'); #变量后面加上括号传参数,调用匿名函数。
利用关键词use闭包函数内部函数使用外部变量
也就是使用use来连接闭包与外界变量,这些变量必须在函数或者类的头部声明。闭包函数从父作用域中继承变量,与使用全局变量不同,全局变量存在一个全局的范围,而闭包父作用域是定义该闭包的函数,不一定是调用它的函数。
//闭包从父作用域继承变量
$message = 'Tacks';
$example = function() use ($message) {
var_dump($message);
};
echo $example();//Tacks
$message = 'world';
echo $example();//Tacks
$example = function() use (&$message) {//如果想要改变它的值要用引用
var_dump($message);
};
echo $example();//world
函数是结构化程序设计的模块,是实现代码重用的核心。有时候为了更好的组织代码,使定义的函数可以在同一个项目的多个文件中使用,通常将自定义的函数组织到同一个文件或者多个文件中,也叫函数库。如果想在其它PHP脚本中使用函数库中定义的函数,就可以用require或者include语言结构来将函数库文件载入程序中。