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:
$ar = $o->me; reset($ar); list($typ, $val) = each($ar);
$out = array('me' => array(), 'mytype' => 2, '_php_class' => null); $expected = each($out);
for(reset($broken);$kv = each($broken);) {...}
list(, $this->result) = each($this->cache_data);
// 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
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.
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.
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.
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);
$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.
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]; }
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
.
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); }
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.
composer require rector/rector --dev
rector.php
configvendor/bin/rector init
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, ]); };
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With