Использование usort в php с частной функцией класса

119

хорошо, использовать usort с функцией не так сложно

Это то, что у меня было раньше в моем линейном коде

function merchantSort($a,$b){
    return ....// stuff;
}

$array = array('..','..','..');

для сортировки я просто делаю

usort($array,"merchantSort");

Сейчас мы обновляем код, удаляем все глобальные функции и помещаем их на соответствующие места. Теперь весь код находится в классе, и я не могу понять, как использовать функцию usort для сортировки массива с параметром, который является методом объекта, а не простой функцией.

class ClassName {
   ...

   private function merchantSort($a,$b) {
       return ...// the sort
   }

   public function doSomeWork() {
   ...
       $array = $this->someThingThatReturnAnArray();
       usort($array,'$this->merchantSort'); // ??? this is the part i can't figure out
   ...

   }
}

Вопрос в том, как вызвать метод объекта внутри функции usort ().

Иб
источник

Ответы:

228

Сделайте свою функцию сортировки статической:

private static function merchantSort($a,$b) {
       return ...// the sort
}

И используйте массив для второго параметра:

$array = $this->someThingThatReturnAnArray();
usort($array, array('ClassName','merchantSort'));
Демиан Брехт
источник
2
Это круто! Я также хотел бы отметить, что функцию сортировки не обязательно объявлять неявно как статический метод; как он все еще работает без :)
Jimbo
@Jimbo - это имеет смысл, поэтому частная функция может использовать переменные экземпляра и класса. Да, это здорово! Также см. Ответ @deceze, где можно пройти $this(аккуратно).
Бен
5
Если вы сделаете функцию статической (что вам нужно), вы можете просто написать usort($array, 'ClassName:merchantSort'), не так ли?
caw
8
Черт, это кажется таким странным способом сделать это. О, PHP, как мы тебя любим.
dudewad
12
@MarcoW., Я думаю, что между ClassName и merchantSort отсутствует секунда ":". Кроме того, если функция используется внутри того же самого класса, я протестировал ее, 'self::merchantSort'и она работает.
Пере
21

Вам нужно пройти, $thisнапример:usort( $myArray, array( $this, 'mySort' ) );

Полный пример:

class SimpleClass
{                       
    function getArray( $a ) {       
        usort( $a, array( $this, 'nameSort' ) ); // pass $this for scope
        return $a;
    }                 

    private function nameSort( $a, $b )
    {
        return strcmp( $a, $b );
    }              

}

$a = ['c','a','b']; 
$sc = new SimpleClass();
print_r( $sc->getArray( $a ) );
Джастин
источник
Второй раздел стал намного лучше. Но в вашем первом примере все еще отсутствует ")".
codecribblr
5

В этом примере я сортирую по полю внутри массива под названием AverageVote.

Вы можете включить метод в вызов, что означает, что у вас больше нет проблемы с областью класса, например ...

        usort($firstArray, function ($a, $b) {
           if ($a['AverageVote'] == $b['AverageVote']) {
               return 0;
           }

           return ($a['AverageVote'] < $b['AverageVote']) ? -1 : 1;
        });
Джеймс К
источник
1
Это имеет смысл только в том случае, если вы используете эту функцию только в этом одном виде. Во многих случаях одно и то же сравнение используется во многих местах.
silk
1
Это было идеально для того, что мне нужно было сделать. Спасибо!
Кристофер Смит,
3

В классе модели Laravel (5.6) я назвал его так, оба метода являются общедоступными статическими, с использованием php 7.2 на 64-разрядной версии Windows.

public static function usortCalledFrom() 

public static function myFunction()

Я позвонил в usortCalledFrom () вот так

usort($array,"static::myFunction")

Ни один из них не работал

usort($array,"MyClass::myFunction")
usort($array, array("MyClass","myFunction")
hrnsky
источник
static::вместо имени класса это то, что мне нужно, спасибо за упоминание.
Sincere