匿名函数//Example1$func=function($param){echo$param;};$func('somestring');//Output:somestring//Example2functioncallFunc($func){$func('somestring');}$printStrFunc=function($str){echo$str;};callFunc($printStrFunc);//可以直接传匿名函数。如果你懂js,这种写法可能会很熟悉callFunc(function($str){echo$str;});ClosurePHP默认情况下,代码块的上下文变量不能在匿名函数中调用,需要通过use关键字。//1。通过闭包获取当前函数环境外的变量值副本。functiongetMoney(){$rmb=1;=6;$func=function()使用($rmb){echo$rmb;//1回显;//错误,未找到dolllar变量};$func();}getMoney();//2.之所以叫副本,是因为匿名函数中的值是通过闭包传递给变量的,值是不能改变的。functiongetMoney(){$rmb=1;$func=function()使用($rmb){$rmb+=2;echo$人民币;//3};$函数();echo$人民币;//还是1没有变化;}getMoney();//3.如果要改变外部变量的值,还是要使用地址传递函数getMoney()的方法{$rmb=1;$func=function()使用(&$rmb){$rmb+=2;echo$人民币;//3};$函数();echo$人民币;//3;}getMoney();//4。函数getMoneyFunc(){$rmb=1;$func=function()use(&$rmb){echo$rmb;//将$rmb的值增加1$rmb++;};返回$函数;//如果匿名函数返回给外界,匿名函数会保存use变量引用的值,外界无法获取这些变量,从而形成'闭包'}$getMoney=getMoneyFunc();$得到金钱();//1$getMoney();//2$getMoney();//3个闭包好处1.减少循环//一个基本的购物车,其中已经添加了一些商品以及每件商品的数量。//有一种方法可以计算购物车中所有商品的总价。此方法使用闭包作为回调函数。购物车类{constPRICE_BUTTER=1.00;constPRICE_MILK=3.00;constPRICE_EGGS=6.95;受保护的$products=array();publicfunctionadd($product,$quantity){$this->products[$product]=$quantity;}publicfunctiongetQuantity($product){returnisset($this->products[$product])?$this->产品[$产品]:false;}publicfunctiongetTotal($tax){$total=0.00;//使用闭包减少循环;$callback=function($quantity,$product)use($tax,&$total){$pricePerItem=constant(__CLASS__."::PRICE_".strtoupper($product));$总计+=($pricePerItem*$quantity)*($tax+1.0);};array_walk($this->products,$callback);返回轮($总计,2);}}$my_cart=newCart;//添加商品到购物车$my_cart->add('butter',1);$my_cart->add('milk',3);$my_cart->add('eggs',6);//打印出含5%销售税的总价.print$my_cart->getTotal(0.05)。"\n";//结果为54.292。减少函数参数functionhtml($code,$id="",$class=""){if($id!=="")$id="id=\"{$id}\"";$类=($类!==“”)?"class=\"$class\"":"";$open="<$code$id$class>";$close="$code>";返回函数($inner=“”)使用($open,$close){返回“$open$inner$close”;};}$tag=html('div','','class');//可读性和可维护性大大提高;echo$tag('div1,div1,div1');echoPHP_EOL;echo$tag('div2,div2,div2');3.释放递归函数//↓↓注意这里的fib一定要用引号引起来,因为第一次会提示Notice:Undefinedvariable,然后后面的fib()会报错;$fib=function($n)使用(&$fib){如果($n==0||$n==1)返回1;返回$fib($n-1)+$fib($n-2);};回声$fib(2)。"\n";//2$lie=$fib;$fib=function(){die('error');};//重写$fib变量echo$lie(5);//错误到达递归释放;4.关于延迟绑定$result=0;$one=function(){var_dump($result);};$two=function()use($result){var_dump($result));};//回调产生时赋值;$四=函数()use($result){//回调产生时赋值0,即$result=0;var_dump($result);};//如果使用引用,可以让使用中的变量完成延迟绑定,也是调用时赋值;$three=function()use(&$result){//1在调用时被赋值,即1,注意对象类型也是引用;var_dump($result);};$result+=1;$one();//输出NULL:$result不在范围内$two();//输出int(0):$result被复制了$three();//输出int(1)$four();//输出int(0)几个带有回调或闭包的函数boolarray_walk(array&$array,callable$funcname[,mixed$userdata=NULL])/***@paramarray$array*@paramcallable$funcname()*@parammixed|NULL$userdata*@returnbool*boolarray_walk(array&$array,callable$funcname[,mixed$userdata=NULL])*/$fruits=array("d"=>"lemon","a"=>"orange","b"=>"banana","c"=>"apple");$test_print=function(&$item2,$key,$prefix){$item2.='10';echo"{$prefix}:$key=>$item2\n";};/*这个结果:d=>lemon这个结果:a=>o范围这个结果:b=>banana这个结果:c=>apple*/array_walk($fruits,$test_print,'thisresult');print_r($fruits);/*Array([d]=>lemon10[a]=>orange10[b]=>banana10[c]=>apple10)*/boolarray_walk_recursive(array&$input,callable$funcname[,mixed$userdata=NULL]$sweet=array('a'=>'apple','b'=>'banana');$fruits=array('sweet'=>$sweet,'sour'=>'lemon');$test_print=function($item,$key){echo"$keyholds$item\n";};array_walk_recursive($fruits,$test_print);/**自动跳过糖果,因为糖果是数组;任何值为数组的键都不会传递给回调函数a持有苹果b持有香蕉酸持有柠檬*/arrayarray_filter(array$array[,callable$callback[,int$flag=0]])$odd=function($var){return($var&1);};$even=function($var){return(!($var&1));};$array1=array("a"=>1,"b"=>2,"c"=>3,"d"=>4,"e"=>5);$array2=array(6,7,8,9,10,11,12);echo"奇数:\n";print_r(array_filter($array1,"odd"););/*Odd:Array([a]=>1[c]=>3[e]=>5)*/echo"Even:\n";print_r(array_filter($array2,"even"));/*Even:Array([0]=>6[2]=>8[4]=>10[6]=>12)*/#即使你想创建一个默认值的数组$entry=array(0=>'foo',1=>false,2=>-1,3=>null,4=>'');print_r(array_filter($entry));0]=>foo[2]=>-1)*/arrayarray_map(callable$callback,array$arr1[,array$array])/***@paramcallable$callback*@paramarray$arr1*@param数组$array*/$func=function($value){return$value*2;};print_r(array_map($func,range(1,5)));/*数组([0]=>2[1]=>4[2]=>6[3]=>8[4]=>10)*/$show_Spanish=function($n,$m){return(“数字$n在西班牙语中称为$m”);};$a=array();1,2,3,4,5);$b=array("uno","dos","tres","cuatro","cinco");$c=array_map($show_Spanish,$a,$b);/**print_r($c);Array([0]=>数字1在西班牙语中称为uno[1]=>数字2称为dos在西班牙语中[2]=>数字3在西班牙语中称为tres[3]=>在西班牙语中数字4称为cuatro[4]=>在西班牙语中数字5称为cinco)*/$map_Spanish=function($n,$m){return(array($n=>$m));};$d=array_map($map_Spanish,$a,$b);print_r($d);/**数组([0]=>数组([1]=>uno)[1]=>数组([2]=>dos)[2]=>数组([3]=>tres)[3]=>数组([4]=>cuatro)[4]=>Array([5]=>cinco))*/mixedarray_reduce(array$input,callable$function[,mixed$initial=NULL])/***使用回调函数迭代归约数组为单个结果值,解释不清楚代码会明白;*@paramarray$input*@paramcallable$function*@parammixed|NULL$initial如果指定了可选参数initial,则参数将被视为数组中的第一个值,或者如果数组为空,则作为最终的返回值*/$rsum=function($result,$value){//$result的初始值为NULL,如果有第三个参数,第三个参数是初值;$结果+=$值;返回$result;};$rmul=function($result,$value){$result*=$value;返回$result;};$a=array(1,2,3,4,5);$x=array();$b=array_reduce($a,$rsum);//(NULL)0+1+2+3+4+5=15;$c=array_reduce($a,$rmul,10);//10*1*2*3*4*5=1200;$d=array_reduce($x,$rsum,"没有要减少的数据");//没有数据减少mixedpreg_replace_callback(mixed$pattern,callable$callback,mixed$subject[,int$limit=-1[,int&$count]])/***@parammixed$patternregularpattern;*@paramcallable$callback*@parammixed$subject*@paramint$limit用于每个模式的每个主题字符串的最大替换数。默认值为-1(无限制)。*@paramint$count如果指定,这个变量将填充替换执行的次数。*mixedpreg_replace_callback(mixed$pattern,callable$callback,mixed$subject[,int$limit=-1[,int&$count]])*///将文本中的年份增加一年。$text="Aprilfoolsdayis04/01/2002\n";$text.="LastChristmaswas12/24/2001\n";//回调函数$next_year=function($matches){//通常:$matches[0]是完成的匹配//$matches[1]是第一个捕获的子组匹配//依此类推返回$matches[1]。($matches[2]+1);};echopreg_replace_callback("|(\d{2}/\d{2}/)(\d{4})|",$next_year,$text);mixedcall_user_func(callable$callback[,mixed$parameter[,mixed$...]])mixedcall_user_func_array(callable$callback,array$param_arr)/***@paramcallable$callback第一个参数是要调用的函数;如果是数组array($classname,$methodname)*@parammixed$parameter第一个前两个参数是排队进入函数的参数;*@parammixed$parameter2*@parammixed$parameter3*..*@return返回值:返回调用函数的结果,否则为FALSE*/$eat=function($fruit,$num){//参数可以bemultipleecho"Youwanttoeat$fruit$numpcs,noproblem\n";};call_user_func($eat,"apple",10);//print:你想吃10个苹果,没问题;call_user_func($eat,"orange",5);//print:Youwanttoeatorange5pcs,noproblem;//调用类方法classmyclass{publicstaticfunctionsay_hello($name,$message){echo"Hello!$name$message";}}//array(类名,静态方法名),参数call_user_func(array('myclass','say_hello'),'dain_sun','goodperson');call_user_func_array(array('myclass','say_hello'),array('dain_sun','goodperson'));//你好!dain_sun好人
