sintaxis qué puede obviar etiquetas caso asp php oop closures

puede - Cierres en PHP... qué, precisamente, son ellos y cuándo necesitarías usarlos?



sintaxis php (6)

Así que estoy programando a lo largo de una manera agradable, actualizada y 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?


Además de los detalles técnicos, los cierres son un prerrequisito fundamental para un estilo de programación conocido como programación orientada a funciones. 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 orientado a objetos, basado en la clase, así como en el anterior procedimental. 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.


Cuando necesite una función en el futuro que realice una tarea que haya decidido ahora.

Por ejemplo, si lee un archivo de configuración y uno de los parámetros le dice que el hash_method para su algoritmo es multiply lugar de square , puede crear un cierre que se usará donde sea que necesite algo.

El cierre se puede crear en (por ejemplo) config_parser() ; crea una función llamada do_hash_method() usando variables locales para config_parser() (desde el archivo de configuración). Siempre que se do_hash_method() , tiene acceso a variables en el ámbito local de config_parser() aunque no se llame en ese ámbito.

Un buen ejemplo hipotético:

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) }


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 funciones y métodos usando una variable que contenga el nombre del método en PHP, que es genial. entonces otra versión del 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 quieres que esté disponible en todas partes, puedes hacer todo estático ...


PHP admitirá cierres de forma nativa en 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 para cierres da 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 de replacement localmente dentro de replace_spaces() , para que no sea:
1) Tapar el espacio de nombres global
2) Hacer que las personas pasen tres años en el futuro se preguntan 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 se asigna como una referencia a $replacement .

Pero recuerda, tienes que esperar PHP 5.3 :)

También puede acceder a las variables fuera de su alcance en un cierre utilizando el uso de la palabra clave. Considera este ejemplo.

// Set a multiplier $multiplier = 3; // Create a list of numbers $numbers = array(1,2,3,4); // Use array_walk to iterate // through the list and multiply array_walk($numbers, function($number) use($multiplier){ echo $number * $multiplier; });

Una excelente explicación se da aquí ¿Qué son php lambdas y cierres?


Un cierre es básicamente una función para la cual se escribe la definición en un contexto pero se 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 arriba.

Esto significa que debería ser posible escribir una definición de función en alguna parte, y usar $ esta variable dentro de la definición de función, luego asignar la definición de función a una variable (otros han dado ejemplos de la sintaxis), luego pasar esta variable a un objeto y llamarlo 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 de hecho no está definido en la definición de clase de ese objeto, sino en otro lugar.

Si no está muy claro, entonces no se preocupe, se aclarará una vez que comience a usarlos.


Aquí hay 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