神奇的PHP匿名函数(Anonymous function)

最近在计划设计一个项目时,意外发现一个PHP匿名函数(或闭包函数)的趣味性。

前言

(当然这都是水文前的废话了)

一直以来,我都追求着把自己项目的代码做到极致精简,又不影响代码可读性。最近计划利用 PHP后端 + Linux开发板 + 一块液晶屏 + 自主开发API···开发一个智能面板放在宿舍耍耍。研究期间,发现别人项目里使用匿名函数做到的精简程度和高效性,这么机灵的思路实在令人钦佩。

排序示例

(在这用数组排序举例)
在这以前,我看到的大多数人使用方式都是通过传入一个函数的名称用到排序器上,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$array = [
['name' => 'apple'],
['name' => 'orange'],
['name' => 'banana']
];

function comparer($a, $b) {
return $a['name'] < $b['name'] ? -1 : 1;
}

usort($array, 'comparer');
?>

但如果引用不仅仅是一个内联函数,则传入一个引用对我来说似乎有点奇怪。所以我开始这样使用:

1
2
3
4
5
6
7
8
9
10
11
<?php
$array = [
['name' => 'apple'],
['name' => 'orange'],
['name' => 'banana']
];

usort($array, function($a, $b) {
return $a['name'] < $b['name'] ? -1 : 1;
});
?>

这样就可以省略掉整行的函数声明。现在如果复杂点,我们可以直接把它赋予到一个变量。然后再引用到usort函数内。

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$array = [
['name' => 'apple'],
['name' => 'orange'],
['name' => 'banana']
];

$comparer = function($a, $b) {
return $a['name'] < $b['name'] ? -1 : 1;
};

usort($array, $comparer);
?>

这样就可以应用在一些针对不需要太多函数声明的情况下,做到代码简洁,也不影响可读性。但是如果需要大量使用排序器,我还是建议你使用第一种情况。

快速分类警告

实验过程中,我也发现如果你像这样执行内联函数,并让返回的结果充当被排序的数组,你可能会遇到Notice: Only variables should be passed by reference这种情况而导致无法运行。举例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

$array = [
['name' => 'apple'],
['name' => 'orange'],
['name' => 'banana']
];

$animal = [
['name' => 'tiger'],
['name' => 'lion'],
['name' => 'pig'],
];

$comparer= function ($a, $b) {
return $a['name'] < $b['name'] ? -1 : 1;
};

usort(array_merge($array, $animal), $comparer);
?>

你需要改成这样:

1
2
3
4
5
6
7
<?php
...

$merged = array_merge($array, $animal);

usort($merged, $comparer);
?>

有点烦人…所以我也想听听其他有PHP经验的大佬能给我一些建议😆