Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I update code that uses the deprecated each() function?

Tags:

php

each

With PHP 7.2, each is deprecated. The documentation says:

Warning This function has been DEPRECATED as of PHP 7.2.0. Relying on this function is highly discouraged.

How can I update my code to avoid using it? Here are some examples:

  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++; } 

When I execute the code on PHP 7.2 I receive the following error:

Deprecated: The each() function is deprecated. This message will be suppressed on further calls

like image 461
yokogeri Avatar asked Sep 29 '17 15:09

yokogeri


People also ask

What is deprecated function in PHP?

As a constantly developing language, newer PHP versions include functions that become deprecated. These functions cease to exist or change the expected result of the function as further versions of PHP are released.

Is PHP 7.2 deprecated?

Important Announcement for PHP Older Versions Available versions of PHP include PHP 5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0, and 8.1 but 5.6, 7.0, 7.1, 7.2, and 7.3 versions are deprecated as of August 15th, 2022.

What is for each and each in PHP?

The each() function is an inbuilt function in PHP and is used to get the current element key-value pair of the given array to which the internal pointer is currently pointing. After returning the key and value of the current element the internal pointer is incremented by one in the array.


2 Answers

  1. For your first two example cases, you could use key() and current() to assign the values you need.

    $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)]; 

    In those cases, you can use next() to advance the cursor afterward, but it may not be necessary if the rest of your code doesn't depend on that.

  3. For the third case, I'd suggest just using a foreach() loop instead and assigning $kv inside the loop.

    foreach ($broken as $k => $v) {      $kv = [$k, $v]; } 
  4. For the fourth case, it looks like the key is disregarded in list(), so you can assign the current value.

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

    Like the first two cases, it may be necessary to advance the cursor with next() depending on how the rest of your code interacts with $this->cache_data.

  5. Fifth can be replaced with a for() loop.

    reset($array); for ($i = 0; $i < 30; $i++) {     $id = key($array);     $item = current($array);     // code     next($array); } 
like image 144
Don't Panic Avatar answered Oct 29 '22 06:10

Don't Panic


2019+ Instant Upgrade of each()

There are actually plenty of cases that each() can be replaced, that's why there are so many different upvoted answers in this question.

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

And:

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

You can replace one by one manually. But isn't there a better way?

I help to migrate projects, where are over 150+ cases like this. I'm lazy so I made a tool called Rector, that converts the code the way above (+ there are more cases, but I don't want to spam the answer).

It's part of the PHP_72 set.


4 Steps to Upgrade your Code

1. Install it

composer require rector/rector --dev 

2. Create rector.php config

vendor/bin/rector init 

3. Add PHP_72 set

<?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. Run it on your code

vendor/bin/rector process src --set php72 

I hope it helps you with your migration.


If there is some bug or anomaly, it's Rector missed case. Create an issue, so we can fix it and make it work for every case possible.

like image 32
Tomas Votruba Avatar answered Oct 29 '22 07:10

Tomas Votruba