如果一个变量名后面有圆括号,PHP引擎将寻找与该变量的值同名的函数,并且尝试解析并执行这个函数
// 用于自定义函数 function test() { echo "this is a test"; } $demo = "test"; echo $demo; // 输出 test echo $demo(); // 输出 this is a test // 也可用于系统函数 $md5 = "md5"; echo $md5; // 输出 md5 echo $md5('123456'); // 输出 e10adc3949ba59abbe56e057f20f883e
回调函数就是调用函数的时候将另一个函数的名称当作参数传递进去,并且在函数体中进行调用
function study($name) { echo "$name is studying PHP basic courses"; } function sing($name) { echo "$name is singing an English song"; } function play($name) { echo "$name is playing video game"; }
使用可变函数声明和应用回调函数
function doWhat($funcName, $name) { $funcName($name); } // 函数doWhat就是我们自己定义的、可以应用回调函数的函数,将自定义的函数名称传递进来,即可调用回调函数 doWhat('study', 'Lucy'); // Lucy is studying PHP basic courses doWhat('sing', 'Lucy'); // Lucy is singing an English song doWhat('play', 'Lucy'); // Lucy is playing video game
如何调用回调函数?
call_user_func('study', 'Lucy'); // Lucy is studying PHP basic courses call_user_func_array('study', array('Lucy')); // Lucy is studying PHP basic courses // 系统函数作为回调函数 echo call_user_func('md5', '123456'); // e10adc3949ba59abbe56e057f20f883e echo call_user_func_array('md5', array('123456')); // e10adc3949ba59abbe56e057f20f883e
为数组的每个元素应用回调函数。返回数组,包含回调函数处理之后数组的所有元素
$arr = array(1, 2, 3 ,4, 5); function toDouble($i): int { $i *= 2; return $i; } $res = array_map('toDouble', $arr); print_r($arr); // 1 2 3 4 5 print_r($res); // 2 6 4 8 10
$arr = array(1, 2, 3, 4, 5); function toThreeTimes(&$i): int { $i *= 3; return $i; } $res = array_walk($arr, 'toThreeTimes'); var_dump($res); // true print_r($arr); // 3 6 9 12 15
$arr = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); function toEvent($i) { if ($i % 2 == 0) return $i; } $res = array_filter($arr, 'toEvent'); print_r($res); // Array ( [1] => 2 [3] => 4 [5] => 6 [7] => 8 [9] => 10 )
function test1($i = 0, &$result = array()) { $i ++; if ($i < 10) { $result[] = $i; test1($i, $result); } # 输出:10987654321(意料之中 12345678910,其实不然) 真正执行 echo $i 是当 a < 10 条件不满足的时候 # 通过 Xdebug 调试可以看到其实有两层循环体,条件满足执行递归,条件不满足开始执行本层函数体循环 echo $i; return $result; } var_dump(test1()); // array 1 2 3 4 5 6 7 8 9
function test2($i = 0, $result = array()) { global $result; $i ++; if ($i < 10) { $result[] = $i; test2($i, $result); } return $result; } var_dump(test2()); // array 1 2 3 4 5 6 7 8 9
仅在第一次调用函数的时候对变量进行初始化,并且保留变量值
# 首先第一次调用,static 对 $i 进行初始化 # 其后每一次执行完都会保留 $i 的值,不再进行初始化 # 相当于直接忽略了 static $i = 0; 这一句 function test3() { static $i = 0; echo $i; $i ++; } test3(); // 0 test3(); // 01 test3(); // 012 test3(); // 0123 test3(); // 01234 function test4($i = 0, $result = array()) { static $result; $i ++; if ($i < 10) { $result[] = $i; test4($i, $result); } return $result; } var_dump(test4()); // array 1 2 3 4 5 6 7 8 9
总结:所谓递归函数,重点是如何处理函数调用自身是如何保证所需要的结果得以在函数间合理"传递"
// 语法 $func = function () { }; // 1、函数里定义一个匿名函数,并且调用它 function content1() { $func = function ($param) { echo $param; }; $func('hello world'); } content1(); // hello world // 2、函数中把匿名函数返回,返回后调用它 function content2(): Closure { return $func = function ($param) { echo $param; }; } $data = content2(); $data('hello world'); // hello world function callbackFunc($func) { $func('hello world'); } $func = function ($param) { echo $param; }; // 3、把匿名函数当做参数传递,并且调用它 callbackFunc($func); // hello world // 4、或者直接将匿名函数进行传递 callbackFunc(function ($param) { echo $param; // hello world }); // 5、闭包使用 use 关键字,use: 连接闭包和外界变量 # 将外层变量传进内层匿名函数,并且调用 function func($param): Closure { return function () use ($param) { echo $param; }; } $func('hello world'); // hello world
php在用户自定义函数中支持可变数量的参数列表
在php5.5及更早的版本中,使用 func_num_args(), func_get_arg(), func_get_args() 函数实现
function func() { // 获取参数数量 echo func_num_args(); // 获取第一个参数的值 print_r(func_get_arg(0)); // 获取所有参数的值 print_r(func_get_args()); } func('a'); // 1 a Array ( [0] => a ) func(1, 2, 3); // 3 1 Array ( [0] => 1 [1] => 2 [2] => 3 ) func(array('a', 'b'), 'c'); // 2 Array ( [0] => a [1] => b ) Array ( [0] => Array ( [0] => a [1] => b ) [1] => c )
在php5.6及以上的版本中,可以使用 … 语法实现
// 使用 ...$params 代替任意数量参数 function func(...$params) { // 获取参数数量 echo count($params); // 获取第一个参数的值 print_r($params[0]); // 获取所有参数的值 print_r($params); } # 输出结果与php5.5使用 func_num_args(), func_get_arg(), func_get_args() 函数一致 func('a'); func(1, 2, 3); func(array('a', 'b'), 'c');