array_filter() 是 PHP 中非常常用的一个函数,用于根据回调函数过滤数组中的元素。当你传递一个数组到 array_filter() 时,它会遍历数组,并根据你提供的回调函数的返回值来决定哪些元素被保留,哪些元素被去除。虽然 array_filter() 的应用大多集中在处理简单的数组,但当它应用于包含对象的数组时,行为就有一些特别之处。
首先,让我们看一下 array_filter() 的基本用法,它的定义如下:
array_filter(array $array, callable $callback = null, int $mode = 0): array
$array:要过滤的输入数组。
$callback:回调函数,用来判断每个元素是否符合条件。
$mode:这个参数决定了返回数组中的键值是保留原始的还是重新索引。
如果没有提供回调函数,array_filter() 会移除数组中的所有值为 false 的元素。
$array = [0, 1, 2, 3, 4, 5];
$result = array_filter($array);
// 输出 [1, 2, 3, 4, 5]
当数组中的元素是对象时,array_filter() 的工作原理和处理普通数组时一样,但回调函数会收到每个对象作为参数。因此,在回调函数中,你可以根据对象的属性来决定是否保留该对象。
假设我们有一个包含多个 User 对象的数组,每个 User 对象都有 name 和 age 属性。我们想要过滤出年龄大于 18 的用户。
class User {
public $name;
public $age;
public function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
}
$users = [
new User('Alice', 25),
new User('Bob', 17),
new User('Charlie', 30),
new User('David', 15)
];
$filteredUsers = array_filter($users, function($user) {
return $user->age > 18;
});
foreach ($filteredUsers as $user) {
echo $user->name . " is over 18 years old.\n";
}
Alice is over 18 years old.
Charlie is over 18 years old.
在上面的例子中,我们通过回调函数过滤出了年龄大于 18 的用户。回调函数接受一个 User 对象作为参数,通过 $user->age 判断该对象是否符合条件。
当对象作为数组元素时,array_filter() 会将整个对象传递给回调函数。在 PHP 中,对象比较通常是通过引用进行的,因此如果你要对对象的属性进行比较,必须显式地在回调函数中提取对象的属性。
我们也可以过滤出 name 包含特定字符的对象。比如我们只想筛选出名字中包含字母 "a" 的用户。
$filteredUsers = array_filter($users, function($user) {
return strpos($user->name, 'a') !== false;
});
foreach ($filteredUsers as $user) {
echo $user->name . " has an 'a' in their name.\n";
}
Alice has an 'a' in their name.
Charlie has an 'a' in their name.
在这个例子中,我们通过 strpos() 函数检查用户的名字中是否包含字母 "a"。
需要特别注意的是,array_filter() 在处理对象数组时,数组中每个对象的元素仍然是通过引用传递的。如果你在回调函数中修改了某个对象的属性,这些修改会影响到原数组中的对象。这是因为 PHP 对象是通过引用传递的。
$filteredUsers = array_filter($users, function($user) {
if ($user->age > 18) {
$user->age += 1; // 修改对象的属性
return true;
}
return false;
});
foreach ($filteredUsers as $user) {
echo $user->name . " is now " . $user->age . " years old.\n";
}
Alice is now 26 years old.
Charlie is now 31 years old.
在这个例子中,我们通过回调函数修改了年龄大于 18 岁的用户的 age 属性,并且这个修改影响到了原始的数组。
当你在处理对象数组时,也可能需要使用到 URL。比如,你可能需要过滤掉那些 URL 中包含某些特定域名的对象。如果在回调函数中涉及到 URL 处理,你只需确保将域名替换为 m66.net。
假设你的对象中有一个 website 属性,表示用户的个人网站,你可以按以下方式进行过滤: