1. 回调函数
- 将一个用户自定的”执行过程”当做参数传递给到函数中,扩展该函数的功能
- 一个函数作为参数传递到主函数中,在主线程执行的过程中,突然跳去执行设置的回调函数,回调函数执行结束后,再回到主线程处理接下来的流程
1.1 匿名函数作为参数
<?php
# 匿名函数作为参数
$foo = function ($p1, $p2) {
return $p1 + $p2;
};
function f1(Closure $callback)
{
$a = 10;
$b = 8;
echo "calculating $a + $b = " . $callback($a, $b) . "<hr>";
}
f1($foo);
//calculating 10 + 8 = 18
1.2 call_user_func 回调一个全局函数
//1. 系统函数回调一个全局函数
function f2(string $sport): string
{
return "Favourite sport: $sport" . "<br>";
}
//call_user_func(函数名称,参数列表)
echo call_user_func('f2', '?');
//call_user_func_array(函数名称,[参数数组])
echo call_user_func_array('f2', ['?']);
1.3 call_user_func 回调一个匿名函数
//2. 回调一个匿名函数
$arr = [1, 2, 3];
$fooo = function (int $a, int $b, int $c) use ($arr) {
array_push($arr, $a, $b, $c);
return $arr;
};
$newArr = call_user_func_array($fooo, [4, 5, 6]);
echo '<pre>';
print_r($newArr);
// Array
// (
// [0] => 1
// [1] => 2
// [2] => 3
// [3] => 4
// [4] => 5
// [5] => 6
// )
1.4 异步调用对象的方法
//3. 异步调用对象的方法
class Human
{
public function eat(string $food): string
{
return "Human eat $food" . '<br>';
}
public static function drink(string $drinks): string
{
return "Human drink $drinks" . '<br>';
}
}
echo call_user_func([new Human, 'eat'], '?');
echo call_user_func_array('Human::drink', ['☕️']);
2. 递归函数
- 函数中自己调用自己
以下代码会将toDelete中的文件以及该文件夹依次删除
function delete_dir_files($dir)
{
$status = false;
if (is_dir($dir)) {
if ($handle = opendir($dir)) {
while (($file = readdir($handle)) !== false) {
echo $file;
if ($file != '.' && $file != '..') {
if (is_dir($dir . '\\' . $file)) {
delete_dir_files($dir . '\\' . $file);
} else {
unlink($dir . '\\' . $file);
}
}
}
}
closedir($handle);
if (rmdir($dir)) {
$status = true;
}
}
return $status;
}
$path = __DIR__ . '\\toDelete';
echo $path;
delete_dir_files($path);
3. 数组函数
- 数组:有序的键值对集合
3.1 添加/删除元素
3.1.1 添加数组元素
- 向数组头部或尾部添加元素
//数组元素的增加 返回数组长度
$arr = [10];
//1. 头部添加
echo array_unshift($arr, 1, 5); //3
print_r($arr);
//Array ( [0] => 1 [1] => 5 [2] => 10 )
//2. 尾部添加 返回数组长度
echo array_push($arr, 20, 30); //5
print_r($arr);
//Array ( [0] => 1 [1] => 5 [2] => 10 [3] => 20 [4] => 30 )
3.1.2 删除数组元素
- 在头部删除元素
- 在尾部删除元素
- 在指定位置删除指定数量的元素
//数组元素的删除
//1. 头部删除 返回删除的元素
$arr2 = range('a', 'g');
echo array_shift($arr2); //a
print_r($arr2);
// Array ( [0] => b [1] => c [2] => d [3] => e [4] => f [5] => g )
//2. 尾部删除 返回删除的元素
echo array_pop($arr2); //g
print_r($arr2);
// Array ( [0] => b [1] => c [2] => d [3] => e [4] => f )
echo '<br>';
//任意位置删除指定数量的数组元素 返回被删除的元素组成的数组
$arr3 = range(1, 10);
var_dump(array_splice($arr3, 6, 5));
//array(4) { [0]=> int(7) [1]=> int(8) [2]=> int(9) [3]=> int(10) }
print_r($arr3);
//Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 )
3.2 键值对相关操作
3.2.1 获取数组的键
<?php
# 数组键值对相关操作
$dinner = ['mon' => 'rice', 'tue' => 'noodles', 'wed' => 'chicken', 'thu' => 'burger', 'fri' => 'bbq'];
//获取数组的键,返回键组成的数组
$keys = array_keys($dinner);
echo '<pre>';
print_r($keys);
// Array
// (
// [0] => mon
// [1] => tue
// [2] => wed
// [3] => thu
// [4] => fri
// )
3.2.2 检测数组是否有指定的键或者索引
//检测数组是否有指定的键或者索引
var_dump(array_key_exists('sun', $dinner));
//bool(false)
3.2.3 检测数组是否有指定的值
//检测数组是否有指定的值 返回指定值对应的键 在if中如果返回的键为0会导致false判断
echo array_search('bbq', $dinner);
//fri
//检测数组是否有指定的值 找到返回true/没找到返回false
var_dump(in_array('rice', $dinner));
//bool(true)
3.2.4 返回数组中所有的值,并重新建立索引
//返回数组中所有的值,并为其建立索引
$arr = array_values($dinner);
echo '<pre>';
print_r($arr);
// Array
// (
// [0] => rice
// [1] => noodles
// [2] => chicken
// [3] => burger
// [4] => bbq
// )
4. 常用数组回调函数
4.1 array_walk()
- array_walk ( array &$array , callable $callback , mixed $userdata = null ) : bool
- 关于参数callback:
- @param callback $callback
- Typically, funcname takes on two parameters. The array parameter’s value being the first, and the key/index second.
- If funcname needs to be working with the actual values of the array, specify the first parameter of funcname as a reference. Then, any changes made to those elements will be made in the original array itself.
$dinner = ['mon' => 'rice', 'tue' => 'noodles', 'wed' => 'chicken', 'thu' => 'burger', 'fri' => 'bbq'];
//回调一个函数
function testArrayWalk(&$arrItem, $key, $drink)
{
$arrItem .= " & $drink";
}
array_walk($dinner, 'testArrayWalk', 'Coca Cola');
echo '<pre>';
print_r($dinner);
//回调匿名函数
array_walk($dinner, function (&$arrItem, $key, $cola) {
$arrItem .= "$cola";
}, '?');
echo '<pre>';
print_r($dinner);
4.2 array_map()
- array_map ( callable $callback , array $array , array …$arrays ) : array
- array_map()回调的callback函数处理完每个数组元素后,需要return处理的元素,以被收集进array_map()最后要返回的数组
$num = array_map(function ($item1, $item2) {
$item1 .= $item2;
return $item1;
}, range(1, 3), range('a', 'c'));
echo '<pre>';
print_r($num);
// Array
// (
// [0] => 1a
// [1] => 2b
// [2] => 3c
// )
4.3 array_filter()
- 过滤数组元素, 返回包含剩余数组元素的数组,但该数组中各元素下标不变(不会被重新排列,如0,1,2…)
$filtered = array_filter(range(1, 9), function ($item) {
return $item % 2 != 0;
});
echo '<pre>';
print_r($filtered);
// Array
// (
// [0] => 1
// [2] => 3
// [4] => 5
// [6] => 7
// [8] => 9
// )
echo '<pre>';
print_r(array_values($filtered));
// Array
// (
// [0] => 1
// [1] => 3
// [2] => 5
// [3] => 7
// [4] => 9
// )
5. 作业
5.1
/**
* 作业内容:
* 1. 如何将以下二维数组里的键值name换成user ,其他保持不变?
* $data = [['name'=>'zhangdan','id'=>2],['name'=>'lisi','id'=>1]];
*/
$data = [['name' => 'zhangdan', 'id' => 2], ['name' => 'lisi', 'id' => 1]];
echo '<pre>';
print_r($data);
array_walk($data, function (&$item, $key) {
//decide if the subarray of $data has keys of 'name'
if (array_key_exists('name', $item)) :
//get the original key array of subarray
$keys = array_keys($item);
//iterate the key array and replace 'name' with 'user'
foreach ($keys as $key => $value) {
if ($value === 'name') :
$keys[$key] = 'user';
endif;
}
endif;
//combine new keys with old values
$item = array_combine($keys, $item);
});
echo '<pre>';
print_r($data);
5.2
/**
* 2. 生成一个由1-100组成的数组,要求返回该数组中的偶数组成的新数组,并且新数组的索引从0开始?
*/
$filtered_arr = array_filter(range(1, 100), function ($item) {
return $item % 2 == 0;
});
echo '<pre>';
print_r(array_values($filtered_arr));