2011-05-11 11 views
5

que tiene una matriz función de clasificación de la siguiente manera:Posible pasar un cierre a la orden en PHP?

public function sortAscending($accounts) 
{ 
    function ascending($accountA, $accountB) { 
     if ($accountA['AmountUntilNextTarget'] == $accountB['AmountUntilNextTarget']) { 
      return 0; 
     } 
     return ($accountA['AmountUntilNextTarget'] < $accountB['AmountUntilNextTarget']) ? -1 : 1; 
    } 
    usort($accounts, $ascending); 

    return $accounts; 
} 

Es evidente que esto no es lo ideal, ya que es difícil codificar la clave para buscar. Pensé que haría esto genérico pasando la clave como un param a la función externa, sin embargo, esto está fuera de alcance en la función interna. Traté de evitar esto mediante el uso de un cierre, lo que tendría acceso al parámetro, en lugar de una función interna de la siguiente manera:

public function sortAscending($accounts, $key) 
{ 
    $ascending = function($accountA, $accountB) { 
     if ($accountsA[$key] == $accountB[$key]) { 
      return 0; 
     } 
     return ($accountA[$key] < $accountB[$key]) ? -1 : 1; 
    } 
    usort($accounts, $ascending); 

    return $accounts; 
} 

Sin embargo usort() sólo acepta un nombre de función, por lo que esto no funciona . ¿Alguien puede ver una (¿mejor?) Forma de lograr esto?

+3

'usort' acepta un parámetro' callback', que puede ser un cierre. El error obvio en su código es la falta ';' después de la definición de la función. Tal vez esa es la causa del error. – lonesomeday

+2

Además de una falta ';', '$ key' tampoco está en el alcance de su cierre. Deberías usarlo: '$ ascending = function ($ acciontA, $ accountB) use ($ key) {..'. – alexn

Respuesta

12

Los cierres también puede heredar las variables del ámbito padre. Cualquiera de estas variables debe declararse en el encabezado de la función . Heredar variables desde el ámbito primario no es el mismo que el uso de variables globales. Las variables globales existen en el alcance global, , que es el mismo independientemente de la función que se esté ejecutando. El alcance padre de un cierre es la función en que se declaró el cierre (no necesariamente la función se llamó de).

  • Tenga en cuenta también que la definición de un cierre y asignarlo a una variable es una operación normal de asignación, por lo que tendrá la ; después del cierre } del cierre.

Después de hacer estos cambios el código sería el siguiente (y debería funcionar bien):

public function sortAscending($accounts, $key) 
{ 
    $ascending = function($accountA, $accountB) use ($key) { 
     if ($accountsA[$key] == $accountB[$key]) { 
      return 0; 
     } 
     return ($accountA[$key] < $accountB[$key]) ? -1 : 1; 
    }; 
    usort($accounts, $ascending); 

    return $accounts; 
} 
+0

Gracias bazmegakapa y otros por su respuesta rápida, esto es realmente útil. Disculpas por el punto y coma perdido que no había recogido en eso, error de colegial. – igniteflow

Cuestiones relacionadas