Usando usort en php con una función privada de clase

119

ok usar usort con una función no es tan complicado

Esto es lo que tenía antes en mi código lineal.

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

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

para ordenar simplemente lo hago

usort($array,"merchantSort");

Ahora estamos actualizando el código y eliminando todas las funciones globales y colocándolas en su lugar apropiado. Ahora todo el código está en una clase y no puedo entender cómo usar la función usort para ordenar la matriz con el parámetro que es un método de objeto en lugar de una función simple

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 pregunta es cómo llamo a un método de objeto dentro de la función usort ()

Ibu
fuente

Respuestas:

228

Haga que su función de clasificación sea estática:

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

Y usa una matriz para el segundo parámetro:

$array = $this->someThingThatReturnAnArray();
usort($array, array('ClassName','merchantSort'));
Demian Brecht
fuente
2
¡Esto es genial! También me gustaría señalar que la función de clasificación no tiene que declararse implícitamente como un método estático; ya que todavía funciona sin :)
Jimbo
@Jimbo: eso tiene sentido, por lo que la función privada puede usar instanciación y variables de clase. ¡Sí, esto es genial! También vea la respuesta de @deceze, donde puede pasar $this(neato).
Ben
5
Si hace que la función sea estática (lo que debería), puede escribir usort($array, 'ClassName:merchantSort'), ¿no?
caw
8
Hombre, esta parece una forma tan extraña de hacer esto. Oh PHP, cuánto te amamos.
dudewad
12
@MarcoW., Creo que falta un segundo ':' entre ClassName y comercianteSort. Además, si la función se usa dentro de la misma clase, la he probado 'self::merchantSort'y está funcionando.
Pere
21

Necesita pasar, $thispor ejemplo:usort( $myArray, array( $this, 'mySort' ) );

Ejemplo 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
fuente
La segunda sección ahora es mucho mejor. Pero todavía le falta ")" en su primer ejemplo.
codescribblr
5

En este ejemplo, estoy ordenando por un campo dentro de la matriz llamado AverageVote.

Podría incluir el método dentro de la llamada, lo que significa que ya no tiene el problema del alcance de la clase, como este ...

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

           return ($a['AverageVote'] < $b['AverageVote']) ? -1 : 1;
        });
James K
fuente
1
Eso tiene sentido solo si está utilizando esta función solo en este tipo. En muchos casos, se utiliza la misma comparación en muchos lugares.
seda
1
Esto fue perfecto para lo que necesitaba hacer. ¡Gracias!
Christopher Smit hace
3

En la clase de modelo Laravel (5.6), lo llamé así, ambos métodos son estáticos públicos, usando php 7.2 en Windows de 64 bits.

public static function usortCalledFrom() 

public static function myFunction()

Llamé a usortCalledFrom () así

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

Ninguno de estos fue trabajo

usort($array,"MyClass::myFunction")
usort($array, array("MyClass","myFunction")
hrnsky
fuente
static::en lugar del nombre de la clase es lo que necesitaba, gracias por mencionarlo.
Sincero