PHP:如何使用带有匿名函数的usort


PHP: how to use usort with anonymous function?

我有一个数组的数组。

我尝试用这段代码根据主数组中每个元素的字段对主数组进行排序。

$field = $this->sorting;
usort($this->out_table["rows"], function($a, $b) use ($field) {
        return strnatcmp($a[$field], $b[$field]);
});

但我有这个

 Parse error: syntax error, unexpected T_FUNCTION 

参考第二行,以"usort"开头的行

我错过了什么?

我的php版本是

PHP 5.2.4-2ubuntu5.27 with Suhosin-Patch 0.9.6.2 (cli) (built: Mar 11 2013 14:14:48)

PHP 5.2不支持匿名函数。匿名函数是Closure类的实例,正如文档所说,它直到5.3才被引入…PS:升级你的PHP版本,5.2是很久以前的EOL’ed。

不过,现在最好编写自己的类,将$field值传递给该类的实例,并使用数组样式的可调用参数:

class Sorter
{
    protected $field = null;
    public function __construct($field)
    {
        $this->field = $field;
    }
    public function sortCallback($a, $b)
    {
        return strnatcmp($a[$this->field], $b[$this->field]);
    }
}
$sorter = new Sorter($field);
usort($this->out_table["rows"], array($sorter, 'sortCallback'));

这基本上就是Closure实例所做的,在这种情况下,匿名函数业务是语法糖。这样的类的优点是,可以向它添加更多的排序回调,并将其作为一种具有sortAscendingsortDescending回调方法的实用程序类来使用。除了可以在实例上设置选项外,还可以在需要的地方使分类器使用严格的(类型和值)比较。。。。

匿名函数是在PHP 5.3中引入的。

如果您一直使用旧版本的PHP,则必须使用函数create_function()。它也产生了一个匿名函数,没有功能上的区别,只是语法不太好,use:的功能也没有等价物

$field = $this->sorting;
usort(
    $this->out_table["rows"],
    create_function(
        // the list of arguments
        '$a, $b',
        // the function body (everything you normally put between { and }
        'global $field; return strnatcmp($a[$field], $b[$field]);'
    )
);

为了避免使用global(如果将此代码放在函数/方法中,它甚至不起作用),您可以尝试编写一个函数,将$field作为参数并创建比较函数(类似于Javascript闭包)。

使用匿名函数很容易做到这一点(但不是必需的),使用create_function()也只需很少的工作即可完成(不过需要转义):

function fn($fld)
{
    $fld = addslashes($fld);
    return create_function(
        '$a, $b',                                          // arguments
        "return strnatcmp('$a['$fld'], '$b['$fld']);"      // function body
    );
}
usort($this->out_table["rows"], fn($field));

函数fn()基本上以旧的PHP方式(5.3之前)从代码中创建匿名函数

请注意,由于比较函数的主体是使用参数$fld的内容生成的,因此对于$fld的某些值,它可能会产生运行时错误(事实上,编译错误,但由于生成函数的主体在运行时创建和解析,因此在为时已晚之前无法检测到)。

另一种比create_function()更好的选择是为此目的创建一个类,如本答案所述。

根据文档,匿名函数是在5.30版本引入的。你的跑步速度低于5.30。

  • 升级您的PHP版本(首先备份服务器)
  • 使用以下解决方案

usort($this->out_table["rows"], 'mySort');
function mySort($a, $b) {
    global $field;
    return strnatcmp($a[$field], $b[$field]);
}