Как решить эту устаревшую функцию каждый php

С PHP 7.2, each устарела. В документации сказано:

Предупреждение Эта функция УСТАРЕЛА с PHP 7.2.0. Полагаться на эту функцию крайне не рекомендуется.

Как я могу обновить свой код, чтобы избежать его использования? Вот некоторые примеры:

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

9 ответов

Решение

Для первых двух примеров вы можете использовать key а также current назначить нужные вам значения.

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

В этих случаях вы можете использовать next перемещать курсор позже, но это может не потребоваться, если остальная часть вашего кода не зависит от этого.

В третьем случае я бы предложил использовать вместо этого цикл foreach и назначить $kv внутри петли.

foreach ($broken as $k => $v) {
    $kv = [$k, $v];
}

В четвертом случае похоже, что ключ игнорируется в list, так что вы можете назначить текущее значение.

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

Как и в первых двух случаях, может потребоваться переместить курсор с помощью next в зависимости от того, как остальная часть вашего кода взаимодействует с $this->cache_data,

№ 5 можно заменить на цикл for.

reset($array);
for ($i = 0; $i < 30; $i++) {
    $id = key($array);
    $item = current($array);
    // code
    next($array);
}

2019+ Мгновенное обновление each()

На самом деле есть много случаев, когда each() можно заменить, поэтому в этом вопросе так много разных ответов.

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

А также:

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

А также:

-list($key, $callback) = each($callbacks);
+$key = key($opt->option);
+$val = current($opt->option);

Вы можете заменить один за другим вручную. Но разве нет лучшего способа?

Я помогаю переносить проекты, где более 150 таких случаев. Я ленивый, поэтому я сделал инструмент под названием Rector, который преобразует код описанным выше способом (+ есть еще случаи, но я не хочу спамить ответ).

Это часть php72 задавать.

Просто установите и используйте его:

composer require rector/rector --dev
vendor/bin/rector process src --level php72

Я надеюсь, что это поможет вам с вашей миграцией.


Если есть какая-то ошибка или аномалия, это пропущено дело Ректора. Создайте проблему, чтобы мы могли ее исправить и заставить ее работать для каждого возможного случая.

Вы можете создать свой собственный each() функция с помощью клавиш (), текущий () и следующий (). затем замените ваши вызовы этой функцией, например так:

<?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);) {...}
reset($array);
while (list($key, $value) = each($array)) {

ОБНОВИТЬ

reset($array);
foreach($array as $key => $value) {

То, что вам определенно не следует делать, это поместить функцию "обратно в php", добавив ее в параметр auto_prepend_file в php.ini.

auto_prepend_file = "/var/www/php/auto_prepend.php"

Затем создайте файл и введите в функцию упаковщик function_exists.

<?php
/**
 * Adds the depreciated each() function back into 7.2
 */
if (!function_exists('each')) {
    function each($arr) {
        $key = key($arr);
        $result = ($key === null) ? false : [$key, current($arr), 'key' => $key, 'value' => current($arr)];
        next($arr);
        return $result;
    }
}

По сути, это объявляет функцию до запуска вашего php-приложения. Когда ваше приложение пытается запустить каждую функцию, оно будет использовать вашу версию.

Это абсолютно не тот способ, которым вы должны подходить к этой проблеме, особенно на производстве! Тем не менее, вы разработчик с ограничениями по времени, и вы просто хотите попробовать произвольные фреймворки для вашего следующего проекта, и они не были обновлены для работы на вашем локальном сервере разработки, не свернув вашу версию php.

Когда вы посвятите себя созданию базы кода для своего проекта, пожалуйста, внесите изменения в принятый ответ, потому что они работают.

Я использовал эмуляцию Ви Зеля каждой функции

Если вы ленивы и хотите починить старый веб-сайт, который использует баджиллионeachвызывает и работал нормально до PHP 8, вы можете исправить это, поместив это в какой-нибудь глобальный файл:

      // PHP 8 compatibility hack
if (!function_exists('each')) {
    function each(&$arr) {
        $key = key($arr);
        if ($key === null) return false;
        $val = current($arr);
        next($arr);
        return [1 => $val, 'value' => $val, 0 => $key, 'key' => $key];
    }
}

В отличие от версии пользователя 840474, это не вызовет бесконечный цикл.

Как насчет использования этой функции?

function array_fetch(array $a) {
   $element = current($a);
   next($a);
   return $element;
}

Для всех комментаторов. Функция foreach не работает с динамическими массивами с изменением количества элементов. Я думаю, что использование пользовательской функции "каждый" Джона Тилли - единственный правильный путь для динамических массивов. Для статических массивов не используйте "каждый" никто. "Foreach" знают все.

Для тех, кто использует Magento2 или аналогичный, не рекомендуется менять основные файлы. Возможно, вы можете понизить версию PHP с 7.2 до 7.1, пока magento не выпустит новую версию.

sudo add-apt-repository ppa:ondrej/php

sudo apt-get update

sudo apt-get install php7.1

sudo apt-get install php7.1-cli php7.1-common php7.1-json php7.1-opcache php7.1-mysql php7.1-mbstring php7.1-mcrypt php7.1-zip php7.1-fpm

sudo a2dismod php7.2

sudo a2enmod php7.1

sudo service apache2 restart

И установить активную версию PHP

sudo update-alternatives --set php /usr/bin/php7.1
Другие вопросы по тегам