Usando usort em php com uma função privada de classe

119

ok usar usort com uma função não é tão complicado

Isso é o que eu tinha antes no meu código linear

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

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

para classificar eu simplesmente faço

usort($array,"merchantSort");

Agora estamos atualizando o código e removendo todas as funções globais e colocando-as em seus lugares apropriados. Agora todo o código está em uma classe e não consigo descobrir como usar a função usort para classificar a matriz com o parâmetro que é um método de objeto em vez de uma função simples

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
   ...

   }
}

A questão é como chamo um método de objeto dentro da função usort ()

Ibu
fonte

Respostas:

228

Torne sua função de classificação estática:

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

E use uma matriz para o segundo parâmetro:

$array = $this->someThingThatReturnAnArray();
usort($array, array('ClassName','merchantSort'));
Demian Brecht
fonte
2
Isso é ótimo! Também gostaria de salientar que a função de classificação não precisa ser declarada implicitamente como um método estático; como ainda funciona sem :)
Jimbo
@Jimbo - isso faz sentido, então a função privada pode usar variáveis ​​de instanciação e classe. Sim, isso é ótimo! Veja também a resposta @deceze, por onde você pode passar $this(neato).
Ben
5
Se você tornar a função estática (o que deve ser feito), você pode simplesmente escrever usort($array, 'ClassName:merchantSort'), não é?
caw
8
Cara, essa parece uma maneira tão estranha de fazer isso. Oh PHP, como te amamos.
dudewad
12
@MarcoW., Acho que falta um segundo ':' entre ClassName e merchantSort. Além disso, se a função estiver sendo usada dentro da mesma classe, eu testei 'self::merchantSort'e ela está funcionando.
Pere
21

Você precisa passar, $thispor exemplo:usort( $myArray, array( $this, 'mySort' ) );

Exemplo completo:

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 ) );
Justin
fonte
A segunda seção agora está muito melhor. Mas ainda falta ")" em seu primeiro exemplo.
codescribblr
5

Neste exemplo, estou classificando por um campo dentro da matriz chamada AverageVote.

Você poderia incluir o método dentro da chamada, o que significa que você não tem mais o problema de escopo de classe, como este ...

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

           return ($a['AverageVote'] < $b['AverageVote']) ? -1 : 1;
        });
James K
fonte
1
Isso só faz sentido se você estiver usando essa função apenas neste tipo. Em muitos casos, a mesma comparação é usada em muitos lugares.
seda
1
Isso era perfeito para o que eu precisava fazer. Obrigado!
Christopher Smit
3

Na classe de modelo do Laravel (5.6), eu a chamei assim, ambos os métodos são public static, usando php 7.2 em windows 64 bit.

public static function usortCalledFrom() 

public static function myFunction()

Eu chamei usortCalledFrom () assim

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

Nenhum desses foi trabalho

usort($array,"MyClass::myFunction")
usort($array, array("MyClass","myFunction")
hrnsky
fonte
static::em vez do nome da classe é o que eu precisava, obrigado por mencioná-lo.
Sincero