我有一个数组数组。
我正在尝试使用此代码根据主数组中每个元素的字段对主数组进行排序。
$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)
答案 0 :(得分:3)
PHP 5.2不支持匿名函数。匿名函数是Closure
类的实例,as the docs say,直到5.3才被引入... PS:_upgrade你的PHP版本,5.2很久以前是EOL了。
但是现在,您最好编写自己的类,将$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
实例的作用,在这种情况下,匿名函数业务是语法糖。像这样的类的优点是你可以为它添加更多的排序回调,并将它作为一种具有sortAscending
和sortDescending
的实用程序类保持方便例如,回调方法。除了您可以在实例上设置的选项,使分类器在需要的地方使用严格(类型和值)比较....
答案 1 :(得分:2)
PHP {5.3}中引入了anonymous functions。
如果您遇到旧版本的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()
)是为此目的创建一个类,如this answer中所述。
答案 2 :(得分:1)
作为per the documentation,版本5.30引入了匿名函数。您的运行速度低于5.30。
usort($this->out_table["rows"], 'mySort');
function mySort($a, $b) {
global $field;
return strnatcmp($a[$field], $b[$field]);
}