¿Cómo puedo actualizar el código que utiliza la función cada() en desuso?

Resuelto yokogeri asked hace 54 años • 13 respuestas

Con PHP 7.2, eachestá en desuso. La documentación dice:

Advertencia Esta función ha quedado DESPRECADA a partir de PHP 7.2.0. Se desaconseja confiar en esta función.

¿Cómo puedo actualizar mi código para evitar usarlo? Aquí hay unos ejemplos:

  1. $ar = $o->me;
    reset($ar);
    list($typ, $val) = each($ar);
    
  2. $out = array('me' => array(), 'mytype' => 2, '_php_class' => null);
    $expected = each($out);
    
  3. for(reset($broken);$kv = each($broken);) {...}
    
  4. list(, $this->result) = each($this->cache_data);
    
  5. // iterating to the end of an array or a limit > the length of the array
    $i = 0;
    reset($array);
    while( (list($id, $item) = each($array)) || $i < 30 ) {
        // code
        $i++;
    }
    

Cuando ejecuto el código en PHP 7.2 recibo el siguiente error:

En desuso: la función each() está en desuso. Este mensaje será suprimido en futuras llamadas.

yokogeri avatar Jan 01 '70 08:01 yokogeri
Aceptado
  1. Para los dos primeros casos de ejemplo, puede utilizar key()y current()para asignar los valores que necesita.

    $ar = $o->me;   // reset isn't necessary, since you just created the array
    $typ = key($ar);
    $val = current($ar);
    
  2. $out = array('me' => array(), 'mytype' => 2, '_php_class' => null);
    $expected = [key($out), current($out)];
    

    En esos casos, puedes usar next()para avanzar el cursor después, pero puede que no sea necesario si el resto de tu código no depende de eso.

  3. Para el tercer caso, sugeriría simplemente usar un foreach()bucle y asignarlo $kvdentro del bucle.

    foreach ($broken as $k => $v) {
         $kv = [$k, $v];
    }
    
  4. Para el cuarto caso, parece que la clave no se tiene en cuenta list(), por lo que puede asignar el valor actual.

    $this->result = current($this->cache_data);
    

    Al igual que en los dos primeros casos, puede ser necesario avanzar el cursor next()dependiendo de cómo interactúa el resto del código $this->cache_data.

  5. El quinto se puede reemplazar con un for()bucle.

    reset($array);
    for ($i = 0; $i < 30; $i++) {
        $id = key($array);
        $item = current($array);
        // code
        next($array);
    }
    
Don't Panic avatar Sep 29 '2017 16:09 Don't Panic

2019+ Actualización instantánea deeach()

En realidad, hay muchos casos que each()se pueden reemplazar, es por eso que hay tantas respuestas diferentes votadas a favor en esta pregunta.

-while (list($key, $callback) = each($callbacks)) {
+foreach ($callbacks as $key => $callback) {
     // ...
 }

Y:

-while (list($key) = each($callbacks)) {
+foreach (array_keys($callbacks) as $key) {
     // ...
 }

Puede reemplazar uno por uno manualmente. ¿Pero no hay una mejor manera?

Ayudo a migrar proyectos, donde hay más de 150+ casos como este. Soy vago, así que creé una herramienta llamada Rector , que convierte el código de la manera anterior (+ hay más casos, pero no quiero enviar spam con la respuesta).

Es parte del PHP_72conjunto.


4 pasos para actualizar tu código

1. Instálalo

composer require rector/rector --dev

2. Crear rector.phpconfiguración

vendor/bin/rector init

3. Agregar PHP_72conjunto

<?php

use Rector\Core\Configuration\Option;
use Rector\Set\ValueObject\SetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
    $parameters->set(Option::SETS, [
        Setlist::PHP_72,
    ]);
};

4. Ejecútelo en su código

vendor/bin/rector process src --set php72

Espero que te ayude con tu migración.


Si hay algún error o anomalía, es el caso perdido de Rector. Cree un problema para que podamos solucionarlo y hacerlo funcionar en todos los casos posibles.

Tomas Votruba avatar Apr 04 '2019 11:04 Tomas Votruba

Encontré una manera de solucionarlo y pensé en compartir la información. Aquí también hay otros casos sobre cómo actualizar los bucles each() a foreach().

Caso 1: valor $ faltante

reset($array);
while (list($key, ) = each($array)) {

Actualización para:

foreach(array_keys($array) as $key) {

Caso 2: Falta la clave $

reset($array);
while (list(, $value) = each($array)) {

Actualización para:

foreach($array as $value) {

Caso 3: No falta nada

reset($array);
while (list($key, $value) = each($array)) {

Actualización para:

foreach($array as $key => $value) {
Petro Mäntylä avatar Feb 10 '2018 13:02 Petro Mäntylä

podrías crear tu propia each()función usando key() , current() y next() . luego reemplace sus llamadas con esa función, así:

<?php
function myEach(&$arr) {
    $key = key($arr);
    $result = ($key === null) ? false : [$key, current($arr), 'key' => $key, 'value' => current($arr)];
    next($arr);
    return $result;
}

1.

$ar = $o->me;
reset($ar);
list($typ, $val) = myEach($ar);

2.

$out = array('me' => array(), 'mytype' => 2, '_php_class' => null);
$expected = myEach($out);

3.

for(reset($broken);$kv = myEach($broken);) {...}
Wee Zel avatar Sep 29 '2017 16:09 Wee Zel