Estoy tratando de implementar una tarea muy simple relacionada con el cierre en PHP que no va bien. Tengo esta solución en JavaScript. ¿Cómo implemento esto en PHP?
const data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] const getChunksOfTwo = () => { let pos = 0 return () => { const start = pos const finish = start + 2 const chunk = data.slice(start, finish) pos++ return chunk } } // To initiate the closure const closureFun = getChunksOfTwo() // Call the closureFun closureFun() // Gives [1, 2] closureFun() // Gives [2, 3] closureFun() // Gives [3, 4]Pero en PHP aparentemente no funciona lo mismo. Estoy intentando esto:
$data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; function getChunksOfTwo($data) { $pos = 0; return function() { $start = $pos; $finish = $start + 2; $chunk = array_slice($data, $start, $finish); $pos++; return $chunk; }; }; // To initiate the closure $closureFun = getChunksOfTwo($data); // Call the closureFun $closureFun(); // Does not give [1, 2] $closureFun(); // Does not give [2, 3]Hay dos problemas en sus códigos php .
Primero, un cierre en PHP encapsula su alcance, lo que significa que no tiene acceso al alcance en el que se define o ejecuta. Sin embargo, es posible heredar variables del ámbito principal (donde se define el cierre) en el cierre con la palabra clave use . Esto hereda las variables by-value , una copia está disponible dentro del cierre usando su nombre original.
Como desea mantener el valor de $pos para cada llamada de función, debe pasarlo por referencia con &$pos .
En segundo lugar, la implementación de array_slice en php es diferente a la de slice en js . Por lo tanto, debe cambiar su entrada en el archivo php.
<?php $data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; function getChunksOfTwo($data) { $pos = 0; return function () use ($data, &$pos) { $chunk = array_slice($data, $pos, 2); $pos++; return $chunk; }; }; // To initiate the closure $closureFun = getChunksOfTwo($data); // Call the closureFun print_r($closureFun()); print_r($closureFun()); print_r($closureFun());Propongo una alternativa, ¿por qué no usar array_chunk ?
$data = [1,2, 3, 4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; $chunk = array_chunk($data, 2); $pos = 0; print_r($chunk[$pos]); $pos++; print_r($chunk[$pos]); $pos++; print_r($chunk[$pos]);Producción:
Array ( [0] => 1 [1] => 2 ) Array ( [0] => 3 [1] => 4 ) Array ( [0] => 5 [1] => 6 )Referencia:
Puedes probar esto
$data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; function getChunksOfTwo($data) { $pos = 0; return function() use(&$pos, $data) { $start = $pos; $finish = 2; $chunk = array_slice($data, $start, $finish); $pos+=2; return $chunk; }; }; // To initiate the closure $closureFun = getChunksOfTwo($data); // Call the closureFun print_r($closureFun()); // gives [1, 2] print_r($closureFun()); // gives [2, 3]O
$data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; function getChunksOfTwo($data) { $chunks = array_chunk($data, 2); $pos = 0; return function() use(&$pos, $data, $chunks) { return $chunks[$pos++]; }; }; // To initiate the closure $closureFun = getChunksOfTwo($data); // Call the closureFun print_r($closureFun()); // gives [1, 2] print_r($closureFun()); // gives [2, 3] & con var significa pasar por fuente de referencia
Debe pasarse por referencia para mutar esa variable, de lo contrario, copia el original y cada nueva llamada tendrá el mismo valor.
salida
Array ( [0] => 1 [1] => 2 ) Array ( [0] => 3 [1] => 4 )