一些函数如usort和call_user_func()可以作为用户自对应函数做为回调参数,回调函数不止是简单的函数,还可以是对象的方法(类方法),包括静态方法。
用户自定义函数作为回调函数的参数,PHP将函数以string形式传递的。可以使用任何内置或者用户自定义函数,除了PHP的语言结构如:array(), echo, empty(), eval(), exit(), isset(), list(), print或者unset()。
1,用usort()函数传递用户自定义函数对美国日期进行排序:
1 <?php 2 /* 3 用usort()函数对美国日期进行排序; 4 */ 5 6 #定义日期,美国格式,是月日年,一般的格式是日月年或者年月日;现在要将它排序为以年月日的格式从大到小或者从小到大排序 7 $dates = array('10-10-2011', '2-17-2010', '2-16-2011', '1-01-2013', '10-10-2012'); 8 9 #使用sort()函数对日期进行从小到大排序 10 echo "<p>Sorting the $dates using the function sort().</p>"; 11 sort($dates); 12 print_r($dates); #打印输出:Array ( [0] => 1-01-2013 [1] => 10-10-2011 [2] => 10-10-2012 [3] => 2-16-2011 [4] => 2-17-2010 ) 13 14 #使用natsort()函数对人类认为的自然排序; 15 echo "<p>Sorting the $dates using the function natsort().</p>"; 16 natsort($dates); 17 print_r($dates); #打印输出:Array ( [0] => 1-01-2013 [3] => 2-16-2011 [4] => 2-17-2010 [1] => 10-10-2011 [2] => 10-10-2012 ) 18 19 #前两种都不符合预期,试用usort()函数对$dates进行排序; 20 function sortDate($a,$b){ 21 if ($a == $b){ 22 return 0; 23 }else{ 24 #将日期进行分割,对应的月日年分别赋值给对应的month,day,year。 25 list($amonth, $aday, $ayear) = explode("-", $a); 26 list($bmonth, $bday, $byear) = explode("-", $b); 27 28 #调用str_pad()函数对月份字符串进行填充。如果月份有两位则不填充,如果不够两位就在其左侧填充0; 29 $amonth = str_pad($amonth, 2, "0", STR_PAD_LEFT); 30 $bmonth = str_pad($bmonth, 2, "0", STR_PAD_LEFT); 31 32 #调用str_pad()函数对日期的字符串进行填充。如果日期有两位数则不填充,如果不够两位就在其左侧填充0; 33 $aday = str_pad($aday, 2, "0", STR_PAD_LEFT); 34 $bday = str_pad($bday, 2, "0", STR_PAD_LEFT); 35 36 #由于年份是四位,就不需要进行填充了,练手的话可以写一下 37 #ayear = str_pad($ayear, 4, "0", STR_PAD_LEFT); 38 #byear = str_pad($byear, 4, "0", STR_PAD_LEFT); 39 40 #对日期进行重组,按年月日的人类习惯进行重组 41 $a = $ayear . $amonth . $aday; 42 $b = $byear . $bmonth . $bday; 43 44 #返回值进行比较 45 return ($a > $b) ? 1: -1; //升序排序 46 #return ($a < $b) ? 1 : -1; //降序排列 47 } 48 } 49 50 echo "<p>Sorting the $dates using the function usort().</p>"; 51 usort($dates, "sortDate"); #函数回调,usort()函数回调自定义函数sortDate(),以字符串的形式作为参数传递到usort()。 52 print_r($dates); #打印输出:Array ( [0] => 2-17-2010 [1] => 2-16-2011 [2] => 10-10-2011 [3] => 10-10-2012 [4] => 1-01-2013 ) 53 ?>
2,call_user_func()调用自定义函数:
1 <?php 2 #定义函数 3 function myCallBackFunction(){ 4 echo "Hello, I am a PHPer!"; 5 } 6 //将自定义函数myCallBackFunction以字符串的形式作为值传递给回调函数call_user_func(); 7 call_user_func('myCallBackFunction'); #输出Hello, I am a PHPer! 8 ?>
回到函数类与对象的应用:
一个已被实例化的object的方法被作为array传递,下表0包含该object,下表1包含方法名。在同一个类里可以访问protected和private方法。
1,简单调用:
1 <?php 2 class myClass{ 3 static function myCallBackMethod(){ 4 echo "Hello, I am PHPer. "; 5 } 6 public function anotherCallBackMethod(){ 7 echo "Trump is a bad guy. His brain owned shit."; 8 } 9 protected function protectedMethod(){ 10 echo "Secret garden 1."; 11 } 12 private function privateMethod(){ 13 echo "Secret garden 2."; 14 } 15 } 16 17 $newclass = new myClass(); #实例化类得到一个$newclass对象 18 //调用静态方法 19 #对象myClass作为数组下标0以及类方法myCallBackMethod作为数组下标1,并且整体作为实参传递给回调函数call_user_func() 20 call_user_func(array('myClass', 'myCallBackMethod')); #输出:Hello, I am PHPer. 21 22 #实例化的对象$newclass作为数组下标0以及类方法myCallBackMethod作为数组下标1,并且整体作为实参传递给回调函数call_user_func() 23 call_user_func(array($newclass, 'myCallBackMethod')); #输出:Hello, I am PHPer. 24 25 #也可以这样调用 26 call_user_func("myClass::myCallBackMethod"); #::是调用静态方法的 27 28 #调用常规方法 29 call_user_func(array('myClass', 'anotherCallBackMethod')); #会报错,但是输出:Trump is a bad guy. His brain owned shit. 30 call_user_func(array($newclass, 'anotherCallBackMethod')); #输出:Trump is a bad guy. His brain owned shit. 31 call_user_func('myClass::anotherCallBackMethod'); #::是调用静态方法的,不过这样子调用好像只会出现一个:Strict standards的错误。输出:Trump is a bad guy. His brain owned shit. 32 33 #调用私有方法和受保护的方法报错; 34 call_user_func(array($newclass, 'protectedMethod')); #不能访问,cannot access protected method 35 call_user_func(array($newclass, 'privateMethod')); #不能访问:cannot access private method 36 ?>
2,父子调用:
1 <?php 2 /* 3 call_user_func()的父子调用 4 */ 5 //定义父类A 6 class A { 7 public static function whoa(){ 8 echo "I am A "; 9 } 10 public function anotherMethodForCall(){ 11 echo "Trump is a bad guy, his brain owned wholly shit."; 12 } 13 protected function MethodProtected(){ 14 echo "Secret Garden."; 15 } 16 private function MethodPrivate(){ 17 echo "Another secret Garden."; 18 } 19 } 20 21 #定义类B并且继承父类A 22 class B extends A { 23 public static function whob(){ 24 echo "I am B "; 25 } 26 } 27 $newa = new A(); 28 $newb = new B(); #实例化子类B,得到对象$newb 29 30 //调用静态方法 31 call_user_func(array('B', 'whob')); #输出I am B; 32 call_user_func(array($newb, 'whob')); #输出I am B; 33 call_user_func(array('B','parent::whoa')); #调用类B的父类方法whoa,输出I am A; 34 35 //调用常规方法 36 call_user_func(array('A', 'anotherMethodForCall')); #报错但是依旧输出:Trump is a bad guy, his brain owned wholly shit. 37 call_user_func(array($newa, 'anotherMethodForCall')); #不报错输出:Trump is a bad guy, his brain owned wholly shit.Hello, PHP 38 call_user_func(array('B', 'anotherMethodForCall')); #报错输出:Trump is a bad guy, his brain owned wholly shit. 39 call_user_func(array($newb, 'anotherMethodForCall')); #不报错输出Trump is a bad guy, his brain owned wholly shit 40 41 call_user_func(array('B', 'parent::anotherMethodForCall')); #报错输出:Trump is a bad guy, his brain owned wholly shit. 42 call_user_func(array($newb, 'parent::anotherMethodForCall')); #不报错输出:Trump is a bad guy, his brain owned wholly shit. 43 44 call_user_func(array($newb, 'parent::MethodProtected')); #报错 cannot access protected method 45 call_user_func(array($newb, 'parent::MethodPrivate')); #报错cannot access private method A 46 #先记下,以后再说 47 class C { 48 public function __invoke($name){ 49 echo "Hello, " .$name. " "; 50 } 51 } 52 $classc = new C(); 53 call_user_func($classc, 'PHP'); #输出:Hello, PHP 54 ?>
array_map()回调函数:
1 <?php 2 /* 3 php使用closure的实例 4 */ 5 #定义函数并赋值给$double 6 $double = function($a){ 7 return $a * 2; 8 }; #如果像这样写,那么大括号的冒号是必须的; 9 10 $numbers = range(1,5); #数字数组1,5赋值给$numbers; 11 12 #调用array_map()函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组,回调函数接收的参数数目应该和传递给array_map()函数的数组数目一致; 13 $new_numbers = array_map($double, $numbers); 14 15 #调用implode()函数将数组元素进行分割,返回由数组元素组合成的字符串;并依次输出. 16 print implode('-', $new_numbers); #输出:2-4-6-8-10 17 18 //-----------------是不是也可以这样写-----------// 19 #定义函数myFunction 20 function myFunction($a){ 21 return $a * 2; 22 } #大括号后面可以不需要冒号; 23 24 $numbers = range(1,5); 25 $new_numbers = array_map('myFunction', $numbers); 26 27 print implode("+",$new_numbers); #输出2+4+6+8+10 28 ?>