0

I am trying to create a simple function to sort an array with usort and I don't understand what's wrong with my code.

For the test, I want to order by the field 'str' in "descending" order.

My array for the test :

$tabCustom = array(
    0 => array(
        'str' => 'cccc',
        'nb' => 1
    ),
    1 => array(
        'str' => 'aaaa',
        'nb' => 3
    ),
    2 => array(
        'str' => 'bbb',
        'nb' => 2
    )
);

Here the code who works well without custom function :

usort($tabCustom, function($a, $b)
{
    $order = 'desc';
    if($order == 'asc')
    {
        return strcasecmp($a['str'], $b['str']);
    }
    elseif($order == 'desc')
    {
        return strcasecmp($b['str'], $a['str']);
    }
});

The result :

Array
(
    [0] => Array
        (
            [str] => cccc
            [nb] => 1
        )

    [1] => Array
        (
            [str] => bbb
            [nb] => 2
        )

    [2] => Array
        (
            [str] => aaaa
            [nb] => 3
        )

)

And now I try to build a custom function based on the same code :

function arraySort($array, $field, $order = 'asc')
{
    usort($array, function($a, $b)
    {
        global $field;
        global $order;
        if($order == 'asc')
        {
            return strcasecmp($a[$field], $b[$field]);
        }
        elseif($order == 'desc')
        {
            return strcasecmp($b[$field], $a[$field]);
        }
    });
}
arraySort($tabCustom, 'str', 'desc');

The wrong result :

Array
(
    [0] => Array
        (
            [str] => cccc
            [nb] => 1
        )

    [1] => Array
        (
            [str] => bbb
            [nb] => 2
        )

    [2] => Array
        (
            [str] => aaaa
            [nb] => 3
        )

)

So I don't understand what's wrong, I have put the global variable for $field and $order because otherwise the code says Undefined variable, but my table sorting doesn't work.

Have you an idea about the problem?

Thanks :)

2
  • as a note (rather than solution): 9/10 globals should never be used, pass in parameters instead Commented Oct 11, 2019 at 10:14
  • ok thanks I will try to not use "global" in the futur Commented Oct 11, 2019 at 11:11

2 Answers 2

2

Progrock is right - you have to use use here... The other problem is - if you define a custom function - you have to use a referenced array. Usort does it already automatically but you have to define it in your own function (the & operator is the magic key for situations like that).

The following should work:

function arraySort(&$array, $field, $order = 'asc')
{
    usort($array, function($a, $b) use ($field, $order)
    {
        return ($order == 'desc')   ?   strcasecmp($b[$field], $a[$field])  :   strcasecmp($a[$field], $b[$field]);
    });
}
arraySort($tabCustom, 'str', 'asc');
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for you answer and for the script, I understand better my mistake now, and I doesn't know the usage of "use" and the "&" operator, if I understand the "&" permit to work on "$tabCustom" without use a "return $array" in my function like a copy ?
yeah something like that - there is a very well written point in the official documentation - take a look @ secure.php.net/manual/en/language.references.pass.php - and pls do me a favour - accept and upvote the answer of progrock or mine ... (this is how SO works if someone provides you with a solution)
1
<?php

function a($foo) {
    b();
}

function b() {
    global $foo;
    var_dump($foo);
}

a('bar');

Output:

NULL

$foo is not in the global scope.

You can use 'use' to inherit variables from the parent scope:

usort($array, function($a, $b) use ($field, $order) {
  // Your code here.
});

3 Comments

the reference is also missig in his own function function arraySort(&array...
@sintakonte good point! Without the reference, the sort occurs on a copy and the original array goes untouched.
Thank you for your anwser, I doesn't know the usage of "use" for a function it's why I have try with "global", thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.