Usare usort in php con una funzione class private


119

ok usare usort con una funzione non è così complicato

Questo è quello che avevo prima nel mio codice lineare

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

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

per ordinare lo faccio semplicemente

usort($array,"merchantSort");

Ora stiamo aggiornando il codice e rimuovendo tutte le funzioni globali e inserendole nella posizione appropriata. Ora tutto il codice è in una classe e non riesco a capire come utilizzare la funzione usort per ordinare l'array con il parametro che è un metodo oggetto invece di una semplice funzione

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

   }
}

La domanda è come posso chiamare un metodo oggetto all'interno della funzione usort ()

Risposte:


228

Rendi statica la tua funzione di ordinamento:

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

E usa un array per il secondo parametro:

$array = $this->someThingThatReturnAnArray();
usort($array, array('ClassName','merchantSort'));

2
È fantastico! Vorrei anche sottolineare che la funzione di ordinamento non deve essere dichiarata implicitamente come metodo statico; dato che funziona ancora senza :)
Jimbo

@Jimbo: questo ha senso, quindi la funzione privata può utilizzare istanze e variabili di classe. Sì, è fantastico! Vedi anche @deceze answer, dove puoi passare $this(neato).
Ben

5
Se rendi statica la funzione (cosa che dovresti), puoi semplicemente scrivere usort($array, 'ClassName:merchantSort'), vero?
caw

8
Amico, questo sembra un modo così strano per farlo. Oh PHP, come ti amiamo.
Dudewad

12
@MarcoW., Penso che manchi un secondo ":" tra ClassName e merchantSort. Inoltre, se la funzione viene utilizzata all'interno della stessa classe, l'ho testata 'self::merchantSort'e funziona.
Pere


21

Devi passare $thisad esempio:usort( $myArray, array( $this, 'mySort' ) );

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

La seconda sezione ora è molto migliore. Ma nel tuo primo esempio manca ancora ")".
codescribblr

5

In questo esempio sto ordinando in base a un campo all'interno dell'array chiamato AverageVote.

Potresti includere il metodo all'interno della chiamata, il che significa che non hai più il problema dell'ambito della classe, come questo ...

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

           return ($a['AverageVote'] < $b['AverageVote']) ? -1 : 1;
        });

1
Ciò ha senso solo se stai usando questa funzione solo in questo tipo. In molti casi lo stesso confronto viene utilizzato in molti luoghi.
seta

1
Questo era perfetto per quello che dovevo fare. Grazie!
Christopher Smit

3

Nella classe del modello Laravel (5.6), l'ho chiamata in questo modo, entrambi i metodi sono statici pubblici, utilizzando php 7.2 su Windows a 64 bit.

public static function usortCalledFrom() 

public static function myFunction()

Ho chiamato usortCalledFrom () in questo modo

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

Nessuno di questi era lavoro

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

static::invece del nome della classe è quello che mi serviva, grazie per averlo menzionato.
Sincero
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.