Así que estoy programando a lo largo de una manera agradable, actualizada, orientada a objetos. Regularmente hago uso de los diversos aspectos de OOP que implementa PHP pero me pregunto cuándo podría necesitar usar cierres. ¿Algún experto que pueda arrojar algo de luz sobre cuándo sería útil implementar cierres?Cierres en PHP ... ¿qué son, exactamente, y cuándo necesitarías usarlos?
Respuesta
PHP apoyará cierres en forma nativa 5.3. Un cierre es bueno cuando desea una función local que solo se utiliza para un propósito pequeño y específico.El RFC for closures dan un buen ejemplo:
function replace_spaces ($text) {
$replacement = function ($matches) {
return str_replace ($matches[1], ' ', ' ').' ';
};
return preg_replace_callback ('/(+) /', $replacement, $text);
}
Esto le permite definir la función replacement
localmente dentro replace_spaces()
, por lo que no es:
1) desordenados en el espacio de nombres global
2) Hacer que la gente tres años después preguntarse por qué hay una función definida globalmente que solo se usa dentro de otra función
Mantiene las cosas organizadas. Observe cómo la función en sí no tiene nombre, simplemente se define y asigna como referencia al $replacement
.
Pero recuerde, usted tiene que esperar para PHP 5.3 :)
Cuando necesite una función en el futuro que realice una tarea que haya decidido ahora.
Por ejemplo, si se lee un archivo de configuración y uno de los parámetros que se dice que el hash_method
para su algoritmo es multiply
en lugar de square
, puede crear un cierre que se utilizará siempre que se necesite para discutir algo.
El cierre se puede crear en (por ejemplo) config_parser()
; crea una función llamada do_hash_method()
usando variables locales a config_parser()
(desde el archivo de configuración). Siempre que se llame al do_hash_method()
, tiene acceso a variables en el ámbito local de config_parser()
aunque no se llame en ese ámbito.
Un buen ejemplo es de esperar hipotética:
function config_parser()
{
// Do some code here
// $hash_method is in config_parser() local scope
$hash_method = 'multiply';
if ($hashing_enabled)
{
function do_hash_method($var)
{
// $hash_method is from the parent's local scope
if ($hash_method == 'multiply')
return $var * $var;
else
return $var^$var;
}
}
}
function hashme($val)
{
// do_hash_method still knows about $hash_method
// even though it's not in the local scope anymore
$val = do_hash_method($val)
}
no puedo simplemente copiar y pegar este ejemplo y ejecutarlo. Preferí un ejemplo que simplemente puedo ejecutar. –
-1 para el código que no funciona. – deceze
Esta respuesta es pobre. Esta es una afirmación sin sentido: "Cuando necesitarás una función en el futuro que realice una tarea que hayas decidido ahora". – Puzbie
Aparte de los detalles técnicos, los cierres son un pre-requisito fundamental para un estilo de programación conocido como la programación orientada función. Un cierre se usa más o menos para lo mismo que se usa un objeto para la programación orientada a objetos; Vincula datos (variables) junto con algún código (una función), que luego puede pasar a otro lugar. Como tal, tienen un impacto en la forma en que escribes los programas o, si no cambias la forma en que escribes tus programas, no tienen ningún impacto.
En el contexto de PHP, son un poco raros, ya que PHP ya es pesado en el paradigma basado en clases, orientado a objetos, así como en el anterior procedural. Por lo general, los idiomas que tienen cierres tienen un alcance léxico completo. Para mantener la compatibilidad con versiones anteriores, PHP no va a obtener esto, por lo que los cierres van a ser un poco diferentes aquí que en otros idiomas. Creo que todavía tenemos que ver exactamente cómo se usarán.
Me gusta el contexto proporcionado por la publicación de troelskn. Cuando quiero hacer algo como el ejemplo de Dan Udey en PHP, uso el patrón de estrategia OO. En mi opinión, esto es mucho mejor que la introducción de una nueva función global cuyo comportamiento se determina en tiempo de ejecución.
http://en.wikipedia.org/wiki/Strategy_pattern
También puede llamar a las funciones y los métodos que utilizan una variable que contiene el nombre del método en PHP, que es grande. así que otra toma en el ejemplo de Dan sería algo como esto:
class ConfigurableEncoder{
private $algorithm = 'multiply'; //default is multiply
public function encode($x){
return call_user_func(array($this,$this->algorithm),$x);
}
public function multiply($x){
return $x * 5;
}
public function add($x){
return $x + 5;
}
public function setAlgorithm($algName){
switch(strtolower($algName)){
case 'add':
$this->algorithm = 'add';
break;
case 'multiply': //fall through
default: //default is multiply
$this->algorithm = 'multiply';
break;
}
}
}
$raw = 5;
$encoder = new ConfigurableEncoder(); // set to multiply
echo "raw: $raw\n"; // 5
echo "multiply: " . $encoder->encode($raw) . "\n"; // 25
$encoder->setAlgorithm('add');
echo "add: " . $encoder->encode($raw) . "\n"; // 10
por supuesto, si usted quiere que sea disponible en todas partes, que sólo podría hacer que todo sea estática ...
Un cierre es básicamente una función para la que se escribe la definición en un contexto pero ejecuta en otro contexto. Javascript me ayudó mucho con la comprensión de estos, porque se utilizan en JavaScript en todo el lugar.
En PHP, son menos efectivos que en JavaScript, debido a las diferencias en el alcance y la accesibilidad de las variables "globales" (o "externas") desde dentro de las funciones. Sin embargo, comenzando con PHP 5.4, los cierres pueden acceder al $ este objeto cuando se ejecuta dentro de un objeto, esto los hace mucho más efectivos.
De esto se tratan los cierres, y debería ser suficiente para entender lo que está escrito anteriormente.
Esto significa que debería ser posible escribir una definición de función en alguna parte, usar $ esta variable dentro de la definición de función, asignar la definición de función a una variable (otros han dado ejemplos de la sintaxis), luego pasar esto variable a un objeto y lo llama en el contexto del objeto, la función puede acceder y manipular el objeto a través de $ this como si fuera uno más de sus métodos, cuando en realidad no está definido en la definición de clase de ese objeto, pero en algún otro lugar.
Si no está muy claro, entonces no se preocupe, se aclarará una vez que comience a usarlos.
Honestamente, esto no está nada claro, ni siquiera para mí, el autor. Básicamente, digo: para conocer qué cierres se verifican en JavaScript, pero tenga en cuenta que el alcance variable es diferente entre JavaScript y PHP. – Rolf
Éstos son ejemplos de cierres en php
// Author: [email protected]
// Publish on: 2017-08-28
class users
{
private $users = null;
private $i = 5;
function __construct(){
// Get users from database
$this->users = array('a', 'b', 'c', 'd', 'e', 'f');
}
function displayUsers($callback){
for($n=0; $n<=$this->i; $n++){
echo $callback($this->users[$n], $n);
}
}
function showUsers($callback){
return $callback($this->users);
}
function getUserByID($id, $callback){
$user = isset($this->users[$id]) ? $this->users[$id] : null;
return $callback($user);
}
}
$u = new users();
$u->displayUsers(function($username, $userID){
echo "$userID -> $username<br>";
});
$u->showUsers(function($users){
foreach($users as $user){
echo strtoupper($user).' ';
}
});
$x = $u->getUserByID(2, function($user){
return "<h1>$user</h1>";
});
echo ($x);
Salida:
0 -> a
1 -> b
2 -> c
3 -> d
4 -> e
5 -> f
A B C D E F
c
- 1. objetos o cierres: ¿cuándo usarlos?
- 2. PHP y mySQL: ¿Cuándo usar htmlentities exactamente?
- 3. ¿Qué son cierres y devoluciones de llamada?
- 4. Cuándo utilizar los punteros, y cuándo no usarlos
- 5. Son cierres en javascript recompiladas
- 6. Cierres: ¿por qué son tan útiles?
- 7. diferencia entre http.context.user y thread.currentprincipal y cuándo usarlos?
- 8. ¿Qué son exactamente los metadatos en SQLAlchemy?
- 9. Algoritmos cercanos a la ordenación: ¿cuándo usarlos?
- 10. ¿Cuándo exactamente OnResultExecuted y OnResultExecuting disparan?
- 11. ¿Qué son vistas para colecciones y cuándo las quieres usar?
- 12. Cierres y Lambda en C#
- 13. ¿Qué es exactamente PATH_INFO en PHP?
- 14. ¿Qué son exactamente las funciones anónimas?
- 15. ¿Qué son exactamente los tipos integrales?
- 16. ¿Qué son exactamente los "servicios de WPF"?
- 17. ¿Qué son exactamente las definiciones, declaraciones y asignaciones de C++?
- 18. ¿Qué son los filtros de intención exactamente?
- 19. ¿Qué son exactamente los recursos no administrados?
- 20. ¿Cuándo son los comentarios "demasiado" y cuándo no son suficientes?
- 21. ¿Qué son los paquetes de sitio en python y puedes instalarlos/usarlos si no eres root?
- 22. ¿Son útiles los patrones de diseño en JavaScript? ¿Y qué son exactamente?
- 23. ASN.1 contra JSON ¿cuándo es apropiado usarlos?
- 24. ¿Exactamente qué es PLINQ?
- 25. ¿Por qué tenemos cierres en JavaScript?
- 26. Descripción de BaseAdapters y cómo usarlos
- 27. ¿Qué son exactamente las "tareas" en el RBAC de Yii?
- 28. std :: function y std :: bind: ¿qué son y cuándo deberían usarse?
- 29. ¿Cuáles son exactamente los requisitos y tareas en Scrum?
- 30. ¿Qué hace exactamente la función gc_enable de PHP?
Esta es una explicación increíble. +1 –
Disfruté de la explicación de ** por qué ** usaría cierres. La mayoría de las personas realmente no entienden eso. +1 –
Esta es una explicación de las funciones anónimas, no una explicación de los cierres. Las funciones anónimas son, como usted dice, simplemente como funciones con nombre, excepto que no son globales. Los cierres, por otro lado, son funciones que contienen variables libres de ámbito léxico (declaradas con "uso"); es decir. pueden copiar y valores de referencia del ámbito en el que están declarados, incluso después de que todo lo demás haya sido recolectado. – Warbo