web-dev-qa-db-ja.com

PHP foreachに対する7つの変更:繰り返し処理している配列内のアイテムを削除できますか?

PHP 7下位互換性のない変更ドキュメント は、foreachについて次のように述べています。

デフォルトの値渡しモードで使用すると、foreachは、配列自体ではなく、反復される配列のコピーで動作します。つまり、反復中に行われた配列の変更は、反復される値に影響を与えません。

私はこれが何を意味するのか理解しようとしていますが、私の主な質問は、このコードがPHP 7でPHP 5.6?

foreach($array as $elementKey => $element) {
    if ($element == 'x') {
        unset($array[$elementKey]);
    }
}

私の2つの質問は次のとおりです。

  1. このコードは引き続き機能しますか?

  2. その場合、PHP 7のこの新しい変更が何を意味するのか、例を挙げて)説明できますか?

編集

Docステートメントを読み直しています。配列の下位の項目の値を変更すると、反復でそれらの項目に到達したときにそれらの変更は存在しないということです。例:

$array = ['x', 'y', 'z'];

$new = [];

foreach($array as $element) {
    if ($element == 'x') {
        $array[2] = 'a';
    }

    $new[] = $element;
}

print_r($new);

ただし、I この例を実行する の場合、PHP versions(このツールを使用したことがないので、どのように機能するかわかりません)。

参照で行うと、aがnewになります。そうでなければ私はしません。しかし、これは両方のバージョンに当てはまるようです。

私が本当に知っておく必要があるのは、非互換性とは何ですか(例として)?

Edit 2

@ -NikiCによる 回答リンクを推奨 は、私が探していた残りのストーリーを提供します。

ほとんどの場合、この変更は透過的であり、パフォーマンスの向上以外の効果はありません。ただし、異なる動作が発生する場合があります。つまり、配列が事前に参照されていた場合です。

$array = [1, 2, 3, 4, 5];
$ref = &$array;
foreach ($array as $val) {
    var_dump($val);
    $array[2] = 0;
}
/* Old output: 1, 2, 0, 4, 5 */
/* New output: 1, 2, 3, 4, 5 */

以前は、参照配列の値ごとの反復は特殊なケースでした。この場合、重複は発生しなかったため、反復中の配列のすべての変更がループに反映されます。 PHP 7ではこの特別なケースはなくなりました:配列の値による繰り返しは、ループ中の変更を無視して、常に元の要素で動作し続けます。

この回答は、配列のコピーを操作するforeachに関して、バージョン間で動作が異なるまれな「特殊なケース」について説明しています。

26
userlite

つまり、今反復している配列を参照することを明示的に指定する必要があるということです。

ただし、サンプルコードでは、とにかくルート配列を参照しているため、参照渡しするかどうかにかかわらず機能します。

<?php
$array = ['x', 'y', 'z'];

foreach($array as $elementKey => $element) {
    if ($element=='x') {
        unset($array[$elementKey]);
    }
}

var_dump($array); // lists 'y' and 'z'

より良い例。この場合、参照なしでforeach内の値を変更しています。そのため、ローカルの変更は失われます。

<?php
$array = ['x', 'y', 'z'];

foreach($array as $element) {
    if ($element=='x') {
        $element = 'a';
    }
}

var_dump($array); // 'x', 'y', 'z'

参照による場合、$elementを配列要素への参照として宣言します。

<?php
$array = ['x', 'y', 'z'];

foreach($array as &$element) {
    if ($element=='x') {
        $element = 'a';
    }
}

var_dump($array); // 'a', 'y', 'z'

実行中のこのコードのデモです PHPのさまざまなバージョンで。

23
Machavity