1.为何要使用函数?php
除了内建的PHP函数,咱们能够建立咱们本身的函数。
函数是能够在程序中重复使用的语句块。
使代码逻辑更清晰
避免过多的全局变量
封装后避免相同逻辑重复代码,只需调用写好的函数便可
便于维护,仅需修改函数逻辑便可完成全部调用该函数的逻辑修改,不须要多处修改
页面加载时函数不会当即执行,函数只有在被调用时才会执行。html
2.函数的结构分析编程
//定义函数 function aa (){ //代码段 } //调用函数 aa();
3.函数的命名规则
函数的命名规范和变量名的命名规范相同。一般函数都是执行一个动做的,所以函数命名时,通常函数中会包含动词闭包
//这是一个简单的命名示例 function aa(){ echo "this is function name aa"; } aa();
4.函数的返回值函数
//用return实现返回 function fan($height,$width){ $area=$height*$width; return $area; } $total=fan(4,3); echo $total ; //结果12,由于3*4=12
5.函数的形参与实参
形参是指function后面小括号里面的参数。
实参是指调用function函数的时候写的参数.性能
function abc($a) //这个$a是形参 { $a++; echo $a; } $a=2; abc($a); //这个$a是实参 输出:3 echo $a; //输出:2 由于传进abc里的是它的一副本 要想在函数内改变该值,能够用引用传递
6.函数的默认值
在php编程中,为自定义函数设定默认值,当用户调用该函数时,若是不给参数指定值,参数会用默认值顶替。ui
function printMe($param = NULL) { print $param; } printMe("This is morenzhi function "); printMe(); //This is morenzhi function
7.函数的强类型参数this
function sum($a,$b) { return $a+$b; } var_dump(sum(1,2)); var_dump(sum(1,2.5)); //int(3) float(3.5)
8.函数的可变参数列表spa
//必须在5.6以上版本才能够运行 function sum(...$numbers) { $acc = 0; foreach( $numbers as $number ) { $acc += $number; } return $acc; } echo sum(1,2,3,4); //输出 //10
9.函数值传递与引用传递
区别
(1)按值传递:函数范围内对值的任何改变在函数外部都会被忽略
(2)按引用传递:函数范围内对值的任何改变在函数外部也能反映出这些修改
优缺点:
A:按值传递时,php必须复制值。特别是对于大型的字符串和对象来讲,这将会是一个代价很大的操做。
B.按引用传递则不须要复制值,对于性能提升颇有好处。code
header('content-type:text/html;charset=utf-8'); $hero = array('no1'=>'蝙蝠侠', 'no2'=>'超人'); $hero2 = &$hero; $hero2['no1'] = '蜘蛛侠'; echo '<pre>'; var_dump($hero); var_dump($hero2); $a = null; $b = &$a; $b = 'abc'; var_dump($a, $b); //结果 /* array(2) { ["no1"]=> string(9) "蜘蛛侠" ["no2"]=> string(6) "超人" } array(2) { ["no1"]=> string(9) "蜘蛛侠" ["no2"]=> string(6) "超人" } string(3) "abc" string(3) "abc" */
10.函数变量做用域
在全部函数外定义的变量拥有全局做用域,在函数内部声明的变量是局部变量,仅能在函数内部访问。要在一个函数中使用全局变量,须要使用global关键字。
//使用global关键字 <?php $x=10; $y=20; function test(){ global $x,$y; $y=$x+$y; } test(); echo $y;//输出30
11.复杂函数-可变函数
若是一个变量名后面有括号,PHP将寻找与该变量值同名的函数,而且尝试执行它。PHP"可变函数"能够用来实现包括回调函数、函数表在内的一些用途。
”可变函数“不能用于语言结构,如echo(),print(),unset(),isset(),empty(),include(),require()等,须要使用自定义的包装函数来将这些结构用做可变函数。
function echoString($str){ echo($str); } $varFun="echoString"; $varFun=("Output String");//输出"Output String"
12.复杂函数-嵌套函数
嵌套函数,是一种有条件全局,你能够控制,在什么状况下提供这样的全局函数给用户使用。但也须要注意,过多的全局函数则会产生“全局污染”,因此,不可多用
function foo() { function bar() { echo "this is qiantao function"; } } /* 如今还不能调用bar()函数,由于它还不存在 */ foo();//结果空 /* 如今能够调用bar()函数了,由于foo()函数 的执行使得bar()函数变为已定义的函数 */ bar();//结果this is qiantao function
13.复杂函数-递归函数
什么是递归函数?
一个函数在它的函数体内调用它自身称为递归调用。 这种函数称为递归函数。
php 递归函数的三种实现方式
(1).利用引用作参数
函数之间原本也是各行其是,即使是同名函数。递归函数是考虑将引用做为参数,成为一个桥梁,造成两个函数间的数据共享。虽然两个函数见貌似操做的是不一样地址,可是实际上操做的是一起内存地址。
function test($a=0,&$result=array()){ $a++; if ($a<10) { $result[]=$a; test($a,$result); } echo $a; return $result; }
本例比较有意思的是 "echo $a" 的值。相信不少人认为是 12345678910 吧? 其实否则,是 1098765432。为何呢?由于函数还没执行"echo $a "前就进行了下一次的函数递归。真正执行echo 是$a<10条件不知足的时候,echo 返回a,返回result, 对于上一层而言,执行完递归函数,开始执行本层的echo $a,依次类推。
(2).利用全局变量
利用全局变量完成递归函数,请确保你确实理解什么是全局变量。global在函数内申明变量不过是外部变量的同名引用。变量的做用范围仍然在本函数范围内。改变这些变量的值,外部同名变量的值天然也改变了。但一旦用了&(引用),同名变量再也不是同名引用。利用全局变量实现递归函数不必理解到这么深的一层,还保持原有对全局变量的见解就能够瓜熟蒂落理解递归函数。
function test1($a=0,$result=array()){ global $result; $a++; if ($a<10) { $result[]=$a; test1($a,$result); } return $result; }
(3).利用静态变量
咱们经常在类中见到static,今天咱们把它利用到递归函数中。请记住static的做用:仅在第一次调用函数的时候对变量进行初始化,而且保留变量值。
function test(){ static $count=0; echo $count; $count++; } test(); test(); test(); test(); test();
请问这一段代码的执行结果是多少?是 00000 么?必然不是。 是 01234。 首先第一次调用test(), static对 $count 进行初始化, 其后每一次执行完都会保留 $count 的值, 再也不进行初始化,至关于直接忽略了 static $count=0; 这一句。
于是将static应用到递归函数做用可想而知。在将须要做为递归函数间做为“桥梁"的变量利用static进行初始化,每一次递归都会保留"桥梁变量"的值。
function test3($a=0){ static $result=array(); $a++; if ($a<10) { $result[]=$a; test3($a); } return $result; }
总结
所谓递归函数,重点是如何处理函数调用自身,是如何保证所须要的结果,得以在函数间合理"传递",固然也有不须要函数之间传值得递归函数
14. 复杂函数-匿名(闭包)函数
匿名函数
提到闭包就不得不想起匿名函数,也叫闭包函数(closures),貌似PHP闭包实现主要就是靠它。声明一个匿名函数是这样
$func = function() { };//带结束符
能够看到,匿名函数由于没有名字,若是要使用它,须要将其返回给一个变量。匿名函数也像普通函数同样能够声明参数,调用方法也相同:
$func = function( $niming ) { echo $niming; }; $func( 'this is niming function' ); //输出:this is niming function
实现闭包
将匿名函数在普通函数中当作参数传入,也能够被返回。这就实现了一个简单的闭包。
下边有三个例子
//例一 //在函数里定义一个匿名函数,而且调用它 function bibao() { $func = function( $str ) { echo $str; }; $func( 'tihs is bibao' ); } bibao(); //输出 //tihs is bibao
//例二 //在函数中把匿名函数返回,而且调用它 function getPrintStrFunc() { $func = function( $str ) { echo $str; }; return $func; } $printStrFunc = getPrintStrFunc(); $printStrFunc( 'this is niming function fanhui' ); //输出 //this is niming function fanhui
//例三 //把匿名函数当作参数传递,而且调用它 function callFunc( $func ) { $func( 'this is niming function canshu chuandi' ); } $printStrFunc = function( $str ) { echo $str; }; callFunc( $printStrFunc ); //输出 //this is niming function canshu chuandi //也能够直接将匿名函数进行传递。若是你了解js,这种写法可能会很熟悉 callFunc( function( $str ) { echo $str; } ); //输出 //this is niming function canshu chuandi
链接闭包和外界变量的关键字:USE
闭包能够保存所在代码块上下文的一些变量和值。PHP在默认状况下,匿名函数不能调用所在代码块的上下文变量,而须要经过使用use关键字。
有人可能会想到,是否能够在匿名函数中改变上下文的变量,但我发现是不能够的:
function getMoney() { $rmb = 1; $func = function() use ( $rmb ) { echo $rmb; //把$rmb的值加1 $rmb++; }; $func(); echo $rmb; } getMoney(); //输出: //1 //1
原来use所引用的也只不过是变量的一个副本而已。可是我想要彻底引用变量,而不是复制。
要达到这种效果,其实在变量前加一个 & 符号就能够了:
function getMoney() { $rmb = 1; $func = function() use ( &$rmb ) { echo $rmb; //把$rmb的值加1 $rmb++; }; $func(); echo $rmb; } getMoney(); //输出: //1 //2