如何在每个 php 中解决这个不推荐使用的功能

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46492621/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 03:13:41  来源:igfitidea点击:

How to resolve this deprecated function each php

php

提问by yokogeri

With PHP 7.2, eachis deprecated. The documentationsays:

在 PHP 7.2 中,each已弃用。文档说:

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

警告该函数自 PHP 7.2.0 起已被弃用。强烈建议不要依赖此功能。

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

回答by Don't Panic

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

对于前两个示例案例,您可以使用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)];
    
  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)];
    

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.

在这些情况下,您可以next()在之后使用光标前进,但如果您的其余代码不依赖于此,则可能没有必要。

  1. For the third case, I'd suggest just using a foreach()loop instead and assigning $kvinside the loop.
  1. 对于第三种情况,我建议只使用foreach()循环并$kv在循环内分配。
    foreach ($broken as $k => $v) {
        $kv = [$k, $v];
    }
  1. For the fourth case, it looks like the key is disregarded in list(), so you can assign the current value.
  1. 对于第四种情况,看起来键在 中被忽略list(),因此您可以分配当前值。
    $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.

与前两种情况一样,可能需要next()根据其余代码与$this->cache_data.

  1. Fifth can be replaced with a for()loop.
  1. 第五个可以用for()循环代替。
    reset($array);
    for ($i = 0; $i < 30; $i++) {
        $id = key($array);
        $item = current($array);
        // code
        next($array);
    }

回答by Wee Zel

you could create your own each()function using key(), current()and next(). then replace your calls with that function, like this:

您可以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.

1.

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

2.

2.

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

3.

3.

for(reset($broken);$kv = myEach($broken);) {...}

回答by Tomá? Votruba

2019+ Instant Upgrade of each()

2019+ 即时升级 each()

Checkout live demo for each eachmigration

每个迁移结帐现场演示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.

实际上有很多情况each()可以替换,这就是为什么在这个问题中有这么多不同的赞成答案。

-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).

我帮助迁移项目,其中有超过 150 多个这样的案例。我很懒,所以我做了一个名为Rector的工具,它按照上面的方式转换代码(+还有更多的情况,但我不想把答案发送给垃圾邮件)。

It's part of the php72set.

这是php72套装的一部分。

Just install and use it:

只需安装并使用它:

composer require rector/rector --dev
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.

如果有一些错误或异常,那就是校长遗漏的情况。创建一个问题,这样我们就可以修复它并使其适用于所有可能的情况。

回答by Stewen Guyon

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

UPDATE

更新

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

回答by Johnatilley

The way you most definitely shouldn't do is put the function "back into php" by adding it to the auto_prepend_file setting in php.ini

您绝对不应该做的方法是通过将函数添加到 php.ini 中的 auto_prepend_file 设置来将函数“放回 php”

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

Then make the file and enter in the function with an function_exists wrapper.

然后制作文件并使用 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;
    }
}

This essentially declares the function before your php application runs. When your application tries to run the each function it'll use your version instead.

这实质上是在您的 php 应用程序运行之前声明了该函数。当您的应用程序尝试运行 each 函数时,它将改用您的版本。

This is absolutely notthe way you should be approaching this problem, especially in production! However you're a developer with time constraints and you just want to try arbitrary frameworks for your next project and they haven't been updated to work on your local development server without winding back your php version.

这绝对不是您解决此问题的方式,尤其是在生产中!然而,您是一名有时间限制的开发人员,您只想为下一个项目尝试任意框架,并且它们尚未更新以在您的本地开发服务器上工作,而不会退回您的 php 版本。

When you've committed to a code base for your project please go ahead and implement the changes in the accepted answer because they do work.

当您为项目提交代码库后,请继续实施已接受答案中的更改,因为它们确实有效。

I used Wee Zel's emulation of the each function

我使用了 Wee Zel 对每个函数的模拟

回答by garsax

What about using this function?

使用这个功能怎么样?

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

回答by claudio

For those who use Magento2 or similar, it is not recommend to change core files. Maybe you can downgrade PHP version from 7.2 to 7.1 till magento have a new release.

对于使用 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

And set the active php version

并设置活动的 php 版本

sudo update-alternatives --set php /usr/bin/php7.1