5

I have never used anonymous functions in PHP before, but I found a piece of code that uses one in order to sort objects

usort($numTurnsPerUser,build_sorter('turns'));

function build_sorter($key) {
    return function ($a, $b) use ($key) {
        return strnatcmp($a[$key], $b[$key]);
    };
}

This code will sort an object by a key (I pass in "turns"). For example, an object that looks like this: (written in JSON, just for readability)

$numTurnsPerUser = {
    "31":{
        "turns":15,
        "order":0
    }, "36":{
        "turns":12, 
        "order":1
    }, "37":{
        "turns":14, 
        "order":2
    }
}

will be sorted into an object that looks like this:

$numTurnsPerUser = {
    "36":{
        "turns":12,
        "order":1
    }, "37":{
        "turns":14,
        "order":2
    }, "31":{
        "turns":15, 
        "order":0
    }
}

This worked great on my local server, which is running PHP 5.3.0, but it fails to work on my online server, which is running "php5" - I'm unable to find any information other than that. I am getting an error

Parse error: syntax error, unexpected T_FUNCTION

I read that PHP < 5.3 cannot use anonymous functions and must use create_function, but the "use" part of the anonymous function has me stumped. Could someone please explain to me what that "use" part of the function is, or better yet, how I can "translate" this to the create_function parameters needed?

hakre
  • 193,403
  • 52
  • 435
  • 836
allicarn
  • 2,859
  • 2
  • 28
  • 47
  • 1
    Let's pretend `create_function` never existed... however, as noted (or discovered?), this is a PHP 5.3+ *only* feature. The Syntax Error is *expected* in PHP 5.2.999 and prior. I hope the title edits give this more direction. Happy coding :) –  May 31 '12 at 01:42
  • @pst if there's a better way to define this function other than `create_function` have at it - I just can't use an anonymous function – allicarn May 31 '12 at 01:45
  • http://stackoverflow.com/questions/10590877/php-create-function-with-nested-arrays It doesn't show "closures", but... seeing how the input is a string. (I can't imagine that this would be good in a larger scale, so perhaps create a class and use a method as the comparator "call-able"?) –  May 31 '12 at 01:48
  • And for how to use a(n object-bound) method as a callback: http://stackoverflow.com/questions/2838197/php-using-a-method-as-a-callback –  May 31 '12 at 01:53
  • "which is running "php5" - I'm unable to find any information other than that." you can find out the version by running `php --version` on the command line. Or in the code of your PHP script, putting `phpinfo();` will print out tons of info about your PHP installation – user102008 May 31 '12 at 18:24

2 Answers2

3

You could do like this:

Class Sorter {
  private $key;

  public function __construct($key) {
    $this->key = $key;
  }

  public function sort($a, $b) {
    return strnatcmp($a[$this->key], $b[$this->key]);
  }
}

usort($numTurnsPerUser, array(new Sorter('key_b'), 'sort'));
xdazz
  • 158,678
  • 38
  • 247
  • 274
0

A literal translation (since you specifically asked for create_function):

function build_sorter($key) {
    return create_function('$a, $b', '$key = '.var_export($key, true).';
        return strnatcmp($a[$key], $b[$key]);
    ');
}

Be careful if you run this a lot, because every time you call create_function it adds a global function that is never destroyed. If you do this too much it will run out of memory.

newacct
  • 119,665
  • 29
  • 163
  • 224