PHP中的callbacks/callables有什么用?
What is the use of callbacks/callables in PHP?
我正在努力思考 PHP 中的回调是什么或做什么。
我看过文档,但它们有什么用?
是否有回调可以做一些简单函数无法完成的事情?
回调用于允许我们将自定义逻辑应用到通用函数,例如 usort()
用于数组排序,如果我们想要比基本排序函数提供的排序逻辑更复杂...按特定 属性 对对象数组进行排序。使用回调,我们可以定义排序规则。
这可以使用我们创建的标准 PHP 函数来定义
$data = [
(object) ['myDate' => '2017-01-12'],
(object) ['myDate' => '2016-12-25'],
(object) ['myDate' => '2017-01-01'],
];
function dateSort($a, $b) {
return $a->myDate <=> $b->myDate;
}
usort($data, 'dateSort');
var_dump($data);
或使用匿名函数
$data = [
(object) ['myDate' => '2017-01-12'],
(object) ['myDate' => '2016-12-25'],
(object) ['myDate' => '2017-01-01'],
];
usort($data, function($a, $b) { return $a->myDate <=> $b->myDate; });
var_dump($data);
所以我们应用于 usort()
的回调允许我们应用其他 sort()
函数无法使用的复杂逻辑。
匿名函数给了我们更大的灵活性:许多数组函数使用的回调,如 usort()
或 array_filter()
自动从函数接收某些参数,例如usort()
从数组中传递两个值进行排序...如果您只是比较这两个值,这不是问题,您可以创建一个简单的函数并使用它;但是如果我们想要排序,以某个值为中心,比如 2016-12-31
,会发生什么,所以我们要根据那个日期的天数 until/since 进行排序;我们需要一个新函数,其中包含日期 hard-coded 作为基准值的函数:
$data = [
(object) ['myDate' => '2017-01-12'],
(object) ['myDate' => '2016-12-25'],
(object) ['myDate' => '2017-01-01'],
];
function dateSort($a, $b) {
return abs(strtotime('2016-12-31') - strtotime($a->myDate)) <=> abs(strtotime('2016-12-31') - strtotime($b->myDate));
}
usort($data, 'dateSort');
var_dump($data);
现在我们进入有趣的部分,如果我们想要动态分配我们的数据透视日期值会发生什么?我们不能向 usort()
回调传递任何额外的参数,那么我们如何在运行时传递 '2017-01-06' 或 '2017-12-26' 的枢轴值?这是匿名回调特别有用的地方,因为我们可以通过 use
:
轻松地将附加参数传递给匿名函数
$data = [
(object) ['myDate' => '2017-01-12'],
(object) ['myDate' => '2016-12-25'],
(object) ['myDate' => '2017-01-01'],
];
$pivotDate = '2017-01-06';
usort(
$data,
function ($a, $b) use ($pivotDate){
return abs(strtotime($pivotDate) - strtotime($a->myDate)) <=> abs(strtotime($pivotDate) - strtotime($b->myDate));
});
var_dump($data);
我正在努力思考 PHP 中的回调是什么或做什么。
我看过文档,但它们有什么用?
是否有回调可以做一些简单函数无法完成的事情?
回调用于允许我们将自定义逻辑应用到通用函数,例如 usort()
用于数组排序,如果我们想要比基本排序函数提供的排序逻辑更复杂...按特定 属性 对对象数组进行排序。使用回调,我们可以定义排序规则。
这可以使用我们创建的标准 PHP 函数来定义
$data = [
(object) ['myDate' => '2017-01-12'],
(object) ['myDate' => '2016-12-25'],
(object) ['myDate' => '2017-01-01'],
];
function dateSort($a, $b) {
return $a->myDate <=> $b->myDate;
}
usort($data, 'dateSort');
var_dump($data);
或使用匿名函数
$data = [
(object) ['myDate' => '2017-01-12'],
(object) ['myDate' => '2016-12-25'],
(object) ['myDate' => '2017-01-01'],
];
usort($data, function($a, $b) { return $a->myDate <=> $b->myDate; });
var_dump($data);
所以我们应用于 usort()
的回调允许我们应用其他 sort()
函数无法使用的复杂逻辑。
匿名函数给了我们更大的灵活性:许多数组函数使用的回调,如 usort()
或 array_filter()
自动从函数接收某些参数,例如usort()
从数组中传递两个值进行排序...如果您只是比较这两个值,这不是问题,您可以创建一个简单的函数并使用它;但是如果我们想要排序,以某个值为中心,比如 2016-12-31
,会发生什么,所以我们要根据那个日期的天数 until/since 进行排序;我们需要一个新函数,其中包含日期 hard-coded 作为基准值的函数:
$data = [
(object) ['myDate' => '2017-01-12'],
(object) ['myDate' => '2016-12-25'],
(object) ['myDate' => '2017-01-01'],
];
function dateSort($a, $b) {
return abs(strtotime('2016-12-31') - strtotime($a->myDate)) <=> abs(strtotime('2016-12-31') - strtotime($b->myDate));
}
usort($data, 'dateSort');
var_dump($data);
现在我们进入有趣的部分,如果我们想要动态分配我们的数据透视日期值会发生什么?我们不能向 usort()
回调传递任何额外的参数,那么我们如何在运行时传递 '2017-01-06' 或 '2017-12-26' 的枢轴值?这是匿名回调特别有用的地方,因为我们可以通过 use
:
$data = [
(object) ['myDate' => '2017-01-12'],
(object) ['myDate' => '2016-12-25'],
(object) ['myDate' => '2017-01-01'],
];
$pivotDate = '2017-01-06';
usort(
$data,
function ($a, $b) use ($pivotDate){
return abs(strtotime($pivotDate) - strtotime($a->myDate)) <=> abs(strtotime($pivotDate) - strtotime($b->myDate));
});
var_dump($data);