realtebo
realtebo

Reputation: 25691

PHP: how to use usort with anonymous function?

I've an array of array.

I'm trying this code to sort main array based of a field of every single element of the main array.

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

But I got this

 Parse error: syntax error, unexpected T_FUNCTION 

Referred to the second line, the one which starts with 'usort'

What am I missing?

My php version is

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

Upvotes: 5

Views: 6417

Answers (3)

axiac
axiac

Reputation: 72256

The anonymous functions were introduced in PHP 5.3.

If you are stuck with an older version of PHP you have to use the function create_function(). It produces an anonymous function too, there is no functional difference, only the syntax is not that nice and there is no equivalent for the functionality of 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]);'
    )
);

To avoid using global (it doesn't even work if you put this code in a function/method) you could try to write a function that gets $field as argument and creates the comparison function (similar with Javascript closures).

This is easy to do (but not needed) using anonymous functions and can be done with little work using create_function() too (it needs escaping, though):

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));

The function fn() basically creates the anonymous function from your code in an old PHP fashion (pre 5.3).

Note that, because the body of the comparison function is generated using the content of argument $fld, for some values of $fld it can produce runtime errors (compilation errors, in fact, but because the body of the generated function is created and parsed at the runtime, they cannot be detected until it's too late).

Another option, better than create_function(), is to create a class for this purpose, as explained in this answer.

Upvotes: 4

ʰᵈˑ
ʰᵈˑ

Reputation: 11365

As per the documentation, anonymous functions were introduced at version 5.30. You're running lower than 5.30.

  • Either upgrade your PHP version (backup server first)
  • Use the solution below

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

Upvotes: 1

Elias Van Ootegem
Elias Van Ootegem

Reputation: 76415

PHP 5.2 doesn't support anonymous functions. Anonymous functions are instances of the Closure class, which as the docs say, wasn't introduced until 5.3... PS: _upgrade your PHP version, 5.2 was EOL'ed ages ago.

For now, though, you're best off writing your own class, pass the $field value to that class' instance and use the array-style callable argument:

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'));

Which is basically what a Closure instance does, the anonymous function business is syntactic sugar in this case. The advantage of a class like this is that you could add some more sort-callbacks to it, and keep it handy as a sort of utility class with a sortAscending and sortDescending callback method, for example. Along with options you can set on the instance that make the sorter use strict (type and value) comparison where it's needed....

Upvotes: 4

Related Questions