如何解决每个PHP已弃用的功能

yok*_*eri 50 php

使用PHP 7.2,each不推荐使用.文件说:

警告此功能自PHP 7.2.0起已废弃.非常不鼓励依赖此功能.

如何更新我的代码以避免使用它?这里有些例子:

  1. $ar = $o->me;
    reset($ar);
    list($typ, $val) = each($ar);
    
    Run Code Online (Sandbox Code Playgroud)
  2. $out = array('me' => array(), 'mytype' => 2, '_php_class' => null);
    $expected = each($out);
    
    Run Code Online (Sandbox Code Playgroud)
  3. for(reset($broken);$kv = each($broken);) {...}
    
    Run Code Online (Sandbox Code Playgroud)
  4. list(, $this->result) = each($this->cache_data);
    
    Run Code Online (Sandbox Code Playgroud)
  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++;
    }
    
    Run Code Online (Sandbox Code Playgroud)

Don*_*nic 50

对于前两个示例案例,您可以使用key()current()分配所需的值.

  1. $ar = $o->me;   // reset isn't necessary, since you just created the array
    $typ = key($ar);
    $val = current($ar);
    
    Run Code Online (Sandbox Code Playgroud)
  2. $out = array('me' => array(), 'mytype' => 2, '_php_class' => null);
    $expected = [key($out), current($out)];
    
    Run Code Online (Sandbox Code Playgroud)

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

对于第三种情况,我建议只使用foreach循环并foreach()在循环内部分配.

    foreach ($broken as $k => $v) {
        $kv = [$k, $v];
    }
Run Code Online (Sandbox Code Playgroud)

对于第四种情况,看起来密钥被忽略$kv,因此您可以分配当前值.

    $this->result = current($this->cache_data);
Run Code Online (Sandbox Code Playgroud)

与前两种情况一样,可能需要list()根据代码的其余部分如何与之交互来推进光标next().

#5可以用for循环替换.

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

  • 对于 4.,我认为用 `list($a, $b) = array(key($arr), current($arr) 替换 `list($a, $b) = each($arr)` 是正确的); next($arr);` 不是吗? (2认同)

Wee*_*Zel 23

你可以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;
}
Run Code Online (Sandbox Code Playgroud)

1.

$ar = $o->me;
reset($ar);
list($typ, $val) = myEach($ar);
Run Code Online (Sandbox Code Playgroud)

2.

$out = array('me' => array(), 'mytype' => 2, '_php_class' => null);
$expected = myEach($out);
Run Code Online (Sandbox Code Playgroud)

3.

for(reset($broken);$kv = myEach($broken);) {...}
Run Code Online (Sandbox Code Playgroud)


Tom*_*uba 11

2019+的即时升级 each()

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

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

和:

-while (list($key) = each($callbacks)) {
+foreach (array_keys($callbacks) as $key) {
     // ...
 }
Run Code Online (Sandbox Code Playgroud)

和:

-list($key, $callback) = each($callbacks);
+$key = key($opt->option);
+$val = current($opt->option);
Run Code Online (Sandbox Code Playgroud)

您可以手动替换一个。但是没有更好的方法吗?

我帮助迁移超过150多个这样的案例的项目。我很懒,所以我制作了一个名为Rector的工具,该工具可以按上述方式转换代码(+的情况更多,但我不想将答案发送垃圾内容)。

这是场景的一部分php72

只需安装并使用它:

composer require rector/rector --dev
vendor/bin/rector process src --set php72
Run Code Online (Sandbox Code Playgroud)

希望它对您的迁移有所帮助。


如果存在一些错误或异常,则是Rector遗漏的情况。创建一个问题,以便我们进行修复并使其在每种情况下都可以使用。

  • 我没有使用那个库,我只是在谷歌上搜索each()替换,在这里看到你的帖子并发现它很有用,但只是想我会指出这个小遗漏,这样你就可以纠正你的帖子。 (2认同)

小智 9

reset($array);
while (list($key, $value) = each($array)) {
Run Code Online (Sandbox Code Playgroud)

更新

reset($array);
foreach($array as $key => $value) {
Run Code Online (Sandbox Code Playgroud)

  • 需要注意的是,它们并不等效,尽管在大多数情况下,一个foreach就足够了–如果您在while循环中修改`$ array`,它将遍历修改后的值。“ foreach”会创建列表的副本并对其进行迭代,因此对“ $ array”的更改不会改变循环。 (2认同)

小智 6

你绝对不应该做的方法是将函数“放回 php”,将其添加到 php.ini 中的 auto_prepend_file 设置中

auto_prepend_file = "/var/www/php/auto_prepend.php"
Run Code Online (Sandbox Code Playgroud)

然后创建文件并使用 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


tri*_*cot 5

以下是一些方法:

标准foreach循环(非常易读):

foreach($this->contents as list($products_id)) {
    $total_items += $this->get_quantity($products_id);
}
Run Code Online (Sandbox Code Playgroud)

或者,减少:

$total_items = array_reduce($this->contents, function($acc, $item) {
    return $acc + $this->get_quantity($products_id[0]);
});
Run Code Online (Sandbox Code Playgroud)

或者,在函数表达式中:

$total_items = array_sum(array_map([$this, 'get_quantity'],
                         array_column($this->contents, 0)));
Run Code Online (Sandbox Code Playgroud)

这些方法都不需要在reset($this->contents);它前面。