web-dev-qa-db-ja.com

PHP foreachは元の配列値を変更します

私は多次元配列の初心者であり、これは大きな時間を悩ませています。

私の配列は次のとおりです:

$fields = array(
    "names" => array(
         "type"         => "text",
         "class"        => "name",
         "name"         => "name",
         "text_before"  => "name",
         "value"        => "",
         "required"     => true,
    )
)

その後、これらの入力が必要な場合、これらの入力が入力されているかどうかをチェックする機能を取得しました。

function checkForm($fields){
    foreach($fields as $field){
        if($field['required'] && strlen($_POST[$field['name']]) <= 0){
            $fields[$field]['value'] = "Some error";
        }
    }
    return $fields;
}

今、私の問題はこの行です

$fields[$field]['value'] = "Some error";

これを返しているので、元の配列の内容を変更したいのですが、foreachループで現在の配列の名前(この例では名前)を取得するにはどうすればよいですか?

118
Jeppe

PHPでは、参照渡し(&)は議論の余地があります。なぜそれが必要なのかがわからないので結果をテストしない限り、使用しないことをお勧めします。

次のことをお勧めします。

foreach ($fields as $key => $field) {
    if ($field['required'] && strlen($_POST[$field['name']]) <= 0) {
        $fields[$key]['value'] = "Some error";
    }
}

したがって、値が必要な場合は基本的に$fieldを使用し、データを変更する必要がある場合は$fields[$key]を使用します。

218
Vlad Preda

&を使用します。

foreach($arr as &$value)
{
     $value = $newVal;
}

&は、配列の値を参照として渡し、変数の新しいインスタンスを作成しません。したがって、参照を変更すると、元の値も変更されます。

http://php.net/manual/en/language.references.pass.php

2018年編集
この回答は、インターネット上の多くの人々に好まれているようです。そのため、より多くの情報と注意事項を追加することにしました。
foreach(または関数)の参照渡しは、簡潔で短い解決策ですが、多くの初心者にとってこれは危険な落とし穴になる可能性があります。

  1. PHPのループには、独自のスコープはありません。 -@マーク・アメリー

    これは、変数が同じスコープで再利用されている場合、深刻な問題になる可能性があります。 別のSO質問は、なぜそれが問題になるのかをうまく示しています。

  2. ForeachはPHP 5の内部配列ポインターに依存しているため、ループ内で変更すると予期しない動作が発生する可能性があります。 -PHP foreachのドキュメント

    同じループでの反復中にレコードを設定解除するか、ハッシュ値(キー)を変更すると、PHP <7で予期しない動作が発生する可能性があります。配列自体が参照の場合、問題はさらに複雑になります。

  3. Foreachパフォーマンス。
    一般的にPHPは、コピーオンライト機能のため、値渡しを好みます。つまり、内部的にPHPは、データのコピーを変更する必要がない限り、重複したデータを作成しません。 foreachの参照渡しによりパフォーマンスが向上するかどうかは議論の余地があります。常にそうであるように、特定のシナリオをテストし、どのオプションがより少ないメモリとCPU時間を使用するかを決定する必要があります。詳細については、NikiCが以下にリンクしているSO投稿を参照してください。

  4. コードの読みやすさ。
    PHPでの参照の作成は、すぐに手に負えなくなるものです。あなたが初心者で、あなたがしていることを完全に制御できない場合は、参照から離れることが最善です。 &演算子の詳細については、このガイドを参照してください。 参照—この記号はPHPで何を意味しますか?
    PHP言語のこの部分について詳しく知りたい場合: PHPリファレンスの説明

@NikiCによるPHP foreachループの内部ロジックの非常に素晴らしい技術的説明:
PHP 'foreach'は実際にどのように機能しますか?

127
Dharman

foreach($fields as &$field){を使用して、元の配列を操作します。

ここ は参照渡しの詳細です。

12
k102
function checkForm(& $fields){
    foreach($fields as $field){
        if($field['required'] && strlen($_POST[$field['name']]) <= 0){
            $fields[$field]['value'] = "Some error";
        }
    }
    return $fields;
}

これは、参照渡しを提案するものです

0
Sagar Kadam