一些函数如usort和call_user_func()可以作为用户自对应函数做为回调参数,回调函数不止是简单的函数,还可以是对象的方法(类方法),包括静态方法。

用户自定义函数作为回调函数的参数,PHP将函数以string形式传递的。可以使用任何内置或者用户自定义函数,除了PHP的语言结构如:array(), echo, empty(), eval(), exit(), isset(), list(), print或者unset()。

1,用usort()函数传递用户自定义函数对美国日期进行排序:

  1. 1 <?php
  2. 2 /*
  3. 3 用usort()函数对美国日期进行排序;
  4. 4 */
  5. 5
  6. 6 #定义日期,美国格式,是月日年,一般的格式是日月年或者年月日;现在要将它排序为以年月日的格式从大到小或者从小到大排序
  7. 7 $dates = array('10-10-2011', '2-17-2010', '2-16-2011', '1-01-2013', '10-10-2012');
  8. 8
  9. 9 #使用sort()函数对日期进行从小到大排序
  10. 10 echo "<p>Sorting the \$dates using the function sort().</p>";
  11. 11 sort($dates);
  12. 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. 13
  14. 14 #使用natsort()函数对人类认为的自然排序;
  15. 15 echo "<p>Sorting the \$dates using the function natsort().</p>";
  16. 16 natsort($dates);
  17. 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. 18
  19. 19 #前两种都不符合预期,试用usort()函数对$dates进行排序;
  20. 20 function sortDate($a,$b){
  21. 21 if ($a == $b){
  22. 22 return 0;
  23. 23 }else{
  24. 24 #将日期进行分割,对应的月日年分别赋值给对应的month,day,year。
  25. 25 list($amonth, $aday, $ayear) = explode("-", $a);
  26. 26 list($bmonth, $bday, $byear) = explode("-", $b);
  27. 27
  28. 28 #调用str_pad()函数对月份字符串进行填充。如果月份有两位则不填充,如果不够两位就在其左侧填充0;
  29. 29 $amonth = str_pad($amonth, 2, "0", STR_PAD_LEFT);
  30. 30 $bmonth = str_pad($bmonth, 2, "0", STR_PAD_LEFT);
  31. 31
  32. 32 #调用str_pad()函数对日期的字符串进行填充。如果日期有两位数则不填充,如果不够两位就在其左侧填充0;
  33. 33 $aday = str_pad($aday, 2, "0", STR_PAD_LEFT);
  34. 34 $bday = str_pad($bday, 2, "0", STR_PAD_LEFT);
  35. 35
  36. 36 #由于年份是四位,就不需要进行填充了,练手的话可以写一下
  37. 37 #ayear = str_pad($ayear, 4, "0", STR_PAD_LEFT);
  38. 38 #byear = str_pad($byear, 4, "0", STR_PAD_LEFT);
  39. 39
  40. 40 #对日期进行重组,按年月日的人类习惯进行重组
  41. 41 $a = $ayear . $amonth . $aday;
  42. 42 $b = $byear . $bmonth . $bday;
  43. 43
  44. 44 #返回值进行比较
  45. 45 return ($a > $b) ? 1: -1; //升序排序
  46. 46 #return ($a < $b) ? 1 : -1; //降序排列
  47. 47 }
  48. 48 }
  49. 49
  50. 50 echo "<p>Sorting the \$dates using the function usort().</p>";
  51. 51 usort($dates, "sortDate"); #函数回调,usort()函数回调自定义函数sortDate(),以字符串的形式作为参数传递到usort()。
  52. 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. 53 ?>

2,call_user_func()调用自定义函数:

  1. 1 <?php
  2. 2 #定义函数
  3. 3 function myCallBackFunction(){
  4. 4 echo "Hello, I am a PHPer!";
  5. 5 }
  6. 6 //将自定义函数myCallBackFunction以字符串的形式作为值传递给回调函数call_user_func();
  7. 7 call_user_func('myCallBackFunction'); #输出Hello, I am a PHPer!
  8. 8 ?>

回到函数类与对象的应用:

  一个已被实例化的object的方法被作为array传递,下表0包含该object,下表1包含方法名。在同一个类里可以访问protected和private方法。

1,简单调用:

  1. 1 <?php
  2. 2 class myClass{
  3. 3 static function myCallBackMethod(){
  4. 4 echo "Hello, I am PHPer.\n";
  5. 5 }
  6. 6 public function anotherCallBackMethod(){
  7. 7 echo "Trump is a bad guy. His brain owned shit.";
  8. 8 }
  9. 9 protected function protectedMethod(){
  10. 10 echo "Secret garden 1.";
  11. 11 }
  12. 12 private function privateMethod(){
  13. 13 echo "Secret garden 2.";
  14. 14 }
  15. 15 }
  16. 16
  17. 17 $newclass = new myClass(); #实例化类得到一个$newclass对象
  18. 18 //调用静态方法
  19. 19 #对象myClass作为数组下标0以及类方法myCallBackMethod作为数组下标1,并且整体作为实参传递给回调函数call_user_func()
  20. 20 call_user_func(array('myClass', 'myCallBackMethod')); #输出:Hello, I am PHPer.
  21. 21
  22. 22 #实例化的对象$newclass作为数组下标0以及类方法myCallBackMethod作为数组下标1,并且整体作为实参传递给回调函数call_user_func()
  23. 23 call_user_func(array($newclass, 'myCallBackMethod')); #输出:Hello, I am PHPer.
  24. 24
  25. 25 #也可以这样调用
  26. 26 call_user_func("myClass::myCallBackMethod"); #::是调用静态方法的
  27. 27
  28. 28 #调用常规方法
  29. 29 call_user_func(array('myClass', 'anotherCallBackMethod')); #会报错,但是输出:Trump is a bad guy. His brain owned shit.
  30. 30 call_user_func(array($newclass, 'anotherCallBackMethod')); #输出:Trump is a bad guy. His brain owned shit.
  31. 31 call_user_func('myClass::anotherCallBackMethod'); #::是调用静态方法的,不过这样子调用好像只会出现一个:Strict standards的错误。输出:Trump is a bad guy. His brain owned shit.
  32. 32
  33. 33 #调用私有方法和受保护的方法报错;
  34. 34 call_user_func(array($newclass, 'protectedMethod')); #不能访问,cannot access protected method
  35. 35 call_user_func(array($newclass, 'privateMethod')); #不能访问:cannot access private method
  36. 36 ?>

2,父子调用:

  1. 1 <?php
  2. 2 /*
  3. 3 call_user_func()的父子调用
  4. 4 */
  5. 5 //定义父类A
  6. 6 class A {
  7. 7 public static function whoa(){
  8. 8 echo "I am A\n";
  9. 9 }
  10. 10 public function anotherMethodForCall(){
  11. 11 echo "Trump is a bad guy, his brain owned wholly shit.";
  12. 12 }
  13. 13 protected function MethodProtected(){
  14. 14 echo "Secret Garden.";
  15. 15 }
  16. 16 private function MethodPrivate(){
  17. 17 echo "Another secret Garden.";
  18. 18 }
  19. 19 }
  20. 20
  21. 21 #定义类B并且继承父类A
  22. 22 class B extends A {
  23. 23 public static function whob(){
  24. 24 echo "I am B\n";
  25. 25 }
  26. 26 }
  27. 27 $newa = new A();
  28. 28 $newb = new B(); #实例化子类B,得到对象$newb
  29. 29
  30. 30 //调用静态方法
  31. 31 call_user_func(array('B', 'whob')); #输出I am B;
  32. 32 call_user_func(array($newb, 'whob')); #输出I am B;
  33. 33 call_user_func(array('B','parent::whoa')); #调用类B的父类方法whoa,输出I am A;
  34. 34
  35. 35 //调用常规方法
  36. 36 call_user_func(array('A', 'anotherMethodForCall')); #报错但是依旧输出:Trump is a bad guy, his brain owned wholly shit.
  37. 37 call_user_func(array($newa, 'anotherMethodForCall')); #不报错输出:Trump is a bad guy, his brain owned wholly shit.Hello, PHP
  38. 38 call_user_func(array('B', 'anotherMethodForCall')); #报错输出:Trump is a bad guy, his brain owned wholly shit.
  39. 39 call_user_func(array($newb, 'anotherMethodForCall')); #不报错输出Trump is a bad guy, his brain owned wholly shit
  40. 40
  41. 41 call_user_func(array('B', 'parent::anotherMethodForCall')); #报错输出:Trump is a bad guy, his brain owned wholly shit.
  42. 42 call_user_func(array($newb, 'parent::anotherMethodForCall')); #不报错输出:Trump is a bad guy, his brain owned wholly shit.
  43. 43
  44. 44 call_user_func(array($newb, 'parent::MethodProtected')); #报错 cannot access protected method
  45. 45 call_user_func(array($newb, 'parent::MethodPrivate')); #报错cannot access private method A
  46. 46 #先记下,以后再说
  47. 47 class C {
  48. 48 public function __invoke($name){
  49. 49 echo "Hello, " .$name. "\n";
  50. 50 }
  51. 51 }
  52. 52 $classc = new C();
  53. 53 call_user_func($classc, 'PHP'); #输出:Hello, PHP
  54. 54 ?>

array_map()回调函数:

  1. 1 <?php
  2. 2 /*
  3. 3 php使用closure的实例
  4. 4 */
  5. 5 #定义函数并赋值给$double
  6. 6 $double = function($a){
  7. 7 return $a * 2;
  8. 8 }; #如果像这样写,那么大括号的冒号是必须的;
  9. 9
  10. 10 $numbers = range(1,5); #数字数组1,5赋值给$numbers;
  11. 11
  12. 12 #调用array_map()函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组,回调函数接收的参数数目应该和传递给array_map()函数的数组数目一致;
  13. 13 $new_numbers = array_map($double, $numbers);
  14. 14
  15. 15 #调用implode()函数将数组元素进行分割,返回由数组元素组合成的字符串;并依次输出.
  16. 16 print implode('-', $new_numbers); #输出:2-4-6-8-10
  17. 17
  18. 18 //-----------------是不是也可以这样写-----------//
  19. 19 #定义函数myFunction
  20. 20 function myFunction($a){
  21. 21 return $a * 2;
  22. 22 } #大括号后面可以不需要冒号;
  23. 23
  24. 24 $numbers = range(1,5);
  25. 25 $new_numbers = array_map('myFunction', $numbers);
  26. 26
  27. 27 print implode("+",$new_numbers); #输出2+4+6+8+10
  28. 28 ?>

PHP可回调类型的更多相关文章

  1. php--->使用callable强制指定回调类型

    php 使用callable强制指定回调类型 如果一个方法需要接受一个回调方法作为参数,我们可以这样写 <?php function dosth($callback){ call_user_fu ...

  2. PHP Callable强制指定回调类型的方法

    如果一个方法需要接受一个回调方法作为参数,我们可以这样写 <?php function dosth($callback){ call_user_func($callback); } functi ...

  3. php之强制回调类型callable

    <?php function demo(callable $fn) { $fn(); } function callback() { echo __FUNCTION__,'<br/> ...

  4. [WCF编程]10.操作:回调操作

    一.回调操作概述 WCF支持服务将调用返回给它的客户端.在回调期间,许多方面都将颠倒过来:服务将成为客户端,客户端将编程服务.回调操作可以用在各种场景和应用程序中,但在涉及事件或者服务发生时间需要通知 ...

  5. WCF分布式开发步步为赢(10):请求应答(Request-Reply)、单向操作(One-Way)、回调操作(Call Back).

    WCF除了支持经典的请求应答(Request-Reply)模式外,还提供了什么操作调用模式,他们有什么不同以及我们如何在开发中使用这些操作调用模式.今天本节文章里会详细介绍.WCF分布式开发步步为赢( ...

  6. php的类型约束

    //如下面的类 class MyClass { /** * 测试函数 * 第一个参数必须为 OtherClass 类的一个对象 */ public function test(OtherClass $ ...

  7. 类型 - PHP手册笔记

    类型简介 PHP 支持 8 种原始数据类型. 四种标量类型: boolean(布尔型,不区分大小写) integer(整型) float(浮点型,也称作double) string(字符串) 两种复合 ...

  8. PHP 不同类型之间的松散和严格比较

    原始数据类型 在比较之前先简单介绍一下PHP的9种原始数据类型,包括 四种标量类型: boolean(布尔型) integer(整型) float(浮点型,也称作 double) string(字符串 ...

  9. php值callback类型和匿名函数(闭包)

    callback.callable类型 自PHP5.4起可以使用callable类型制定回调类型callback. 本文档基于同样理由使用callback类型信息. 一些函数如call_user_fu ...

随机推荐

  1. Spring 源码阅读环境的搭建

    前言 本文记录了 Spring 源码环境的搭建方式,以及踩过的那些坑!​当前版本:5.3.2-SNAPSHOT. 环境准备 Git JDK master 分支需要 JDK 11 5.2.x 分支, J ...

  2. 【mq读书笔记】定时消息

    mq不支持任意的时间京都,如果要支持,不可避免的需要在Broker层做消息排序,加上持久化方面的考量,将不可避免地带来巨大的性能消耗,所以rocketMQ只支持特定级别的延迟消息. 在Broker短通 ...

  3. SQL优化之SQL 进阶技巧(下)

    上文( SQL优化之SQL 进阶技巧(上) )我们简述了 SQL 的一些进阶技巧,一些朋友觉得不过瘾,我们继续来下篇,再送你 10 个技巧 一. 使用延迟查询优化 limit [offset], [r ...

  4. PyQt(Python+Qt)学习随笔:Qt Designer中QAbstractButton派生按钮部件的text属性

    text属性保存按钮上显示的文字,如果按钮未设置文字则为空字符串.如果文字中包含有与符号('&'),则该按钮会自动设置一个快捷键,快捷键就是'&'后第一个字符,显示时会在该字符下加下划 ...

  5. PHP代码审计分段讲解(13)

    代码审计分段讲解之29题,代码如下: <?php require("config.php"); $table = $_GET['table']?$_GET['table']: ...

  6. PHP代码审计分段讲解(12)

    28题 <!DOCTYPE html> <html> <head> <title>Web 350</title> <style typ ...

  7. CTF写脚本

    今天总结一下CTF如何写脚本快速得分....(比较菜,能力有限,大佬勿喷) 所谓的写脚本得分,就是利用了 python爬虫的思想,如果之前没有听说过的话,可以去爬虫的相关语法.如果是看网上的视频的话, ...

  8. 对flask的学习

    任务需求:一个登录,注册页面 任务环境:pycharm 2018 专业版,python3.7,win 10专业版 ------------------------------------------- ...

  9. MySQL入门看这一篇就够了

    MySQL JavaEE:企业级Java开发 web阶段 分为1.前端(页面,展示数据库中的数据) 2.后台(连接点:链接数据库JDBC.Mybatis,链接前端(控制视图跳转,给前端传递数据)) 3 ...

  10. this.$options.data()实战之重置data

    刚刚看到这个方法学习了一下,然后想到正在开发的项目有一个需要重置data的操作,正好拿来使用一下,节省了好多代码,美滋滋...