Как разрешить эту устаревшую функцию каждый 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++;
    }
    

Ответ 1

В первых двух примерах вы можете использовать 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() для последующего перемещения курсора, но это может не потребоваться, если остальная часть вашего кода не зависит от этого.

  1. В третьем случае я бы предложил использовать вместо этого цикл foreach() и назначить $kv внутри цикла.
    foreach ($broken as $k => $v) {
        $kv = [$k, $v];
    }
  1. В четвертом случае похоже, что ключ игнорируется в list(), поэтому вы можете назначить текущее значение.
    $this->result = current($this->cache_data);

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

  1. Пятый может быть заменен for() цикл for().
    reset($array);
    for ($i = 0; $i < 30; $i++) {
        $id = key($array);
        $item = current($array);
        // code
        next($array);
    }

Ответ 2

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

<?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);) {...}

Ответ 3

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

ОБНОВИТЬ

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

Ответ 4

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

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


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

Ответ 5

То, что вам определенно не следует делать, это поместить функцию "обратно в 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.

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

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

Ответ 6

Для тех, кто использует 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

Ответ 7

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

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