PHP foreach orijinal dizi değerlerini değiştirir


143

Çok boyutlu dizilerde çok yeniyim ve bu bana büyük zaman ayırıyor.

Dizim aşağıdaki gibidir:

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

Daha sonra bu girişlerin gerekli olup olmadığını kontrol eden bir fonksiyon aldım.

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

Şimdi benim sorunum bu çizgi

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

Bu döndürdüğüm için orijinal dizinin içeriğini değiştirmek istiyorum, ancak geçerli dizinin adını (bu örnekte adlar) benim foreach döngüsünde nasıl alabilirim?



1
Ne kadar yeni olursanız olun (ya da eskiden olursanız olun) - bu PHP belgelerinden okuyabileceğiniz bir şeydir: php.net/manual/en/control-structures.foreach.php
Nikolay Ivanov

Yanıtlar:


261

PHP'de, reference ( &) yöntemiyle iletme ... tartışmalıdır. Neden ihtiyacınız olduğunu bilmediğiniz sürece sonuçları kullanmamanızı tavsiye ederim.

Aşağıdakileri yapmanızı tavsiye ederim:

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

Temel olarak $field, değerlere $fields[$key]ihtiyacınız olduğunda ve verileri değiştirmeniz gerektiğinde kullanın.


Güzel, bu işe yarıyor! İlk önce böyle bir şey denedim, ama sanırım bir yere berbat ettim :) Şimdi örneğinizi binlerce kez kullanacağım ve asla unutmayacağım! :)
Jeppe

Yardımcı oldu sevindim. Ayrıca, bağlantı verdiğim makaleyi ve ayrıca foreach için resmi belgeleri de okumanızı tavsiye ederim ( php.net/manual/ro/control-structures.foreach.php )
Vlad Preda

4
Alt satır: dizi / değişkeni değiştirecekseniz, bir başvuru kullanmalısınız. Daha hızlı, daha temiz ve daha okunabilir.
Lulu

2
Merak ediyorum neden referansla geçmek foreachtartışmalı olmalı? Gizli yan etkileri olan bir işlev çağrısı gibi değil.
UncaAlby

1
"Referans ile geçme" veya "referansla geçme kötüdür" yerine "referans (&) ile geçiş ... tartışmalı" dediğiniz için teşekkür ederiz. Alev savaşı başlatma olasılığı daha az. :)
Fasulye Sean

163

Kullanım &:

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

&dizinin bir değerini başvuru olarak geçirir ve değişkenin yeni bir örneğini oluşturmaz. Böylece referansı değiştirirseniz orijinal değer değişir.

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

Edit 2018
Bu cevap internetteki birçok insan tarafından tercih ediliyor gibi görünüyor, bu yüzden daha fazla bilgi ve dikkat ifadeleri eklemeye karar verdim.
Referans foreach(veya işlevler) ile referansla geçmek temiz ve kısa bir çözüm olsa da, birçok yeni başlayan için bu tehlikeli bir tuzak olabilir.

  1. PHP'deki döngülerin kendi kapsamları yoktur. - @Mark Amery

    Değişkenler aynı kapsamda yeniden kullanıldığında bu ciddi bir sorun olabilir. Başka bir SO sorusu, bunun neden bir sorun olabileceğini güzel bir şekilde göstermektedir.

  2. Foreach, PHP 5'teki dahili dizi işaretçisine dayandığından, döngü içinde değiştirilmesi beklenmedik davranışlara yol açabilir. - Foreach için PHP belgeleri

    Aynı döngüdeki yineleme sırasında bir kaydın ayarının kaldırılması veya karma değerinin (anahtar) değiştirilmesi, PHP <7'de potansiyel olarak beklenmedik davranışlara neden olabilir. Dizinin kendisi bir başvuru olduğunda sorun daha da karmaşıklaşır.

  3. Her performans.
    Genel olarak PHP yazma üzerine kopyalama özelliği nedeniyle değere göre geçişi tercih eder. Bu, kopyanın değiştirilmesi gerekmediği sürece dahili PHP'nin yinelenen bir veri oluşturmayacağı anlamına gelir. Referans yoluyla geçişin foreachperformans iyileştirmesi sunup sunmayacağı tartışmalıdır . Her zaman olduğu gibi, özel senaryonuzu test etmeniz ve hangi seçeneğin daha az bellek ve işlemci zamanı kullandığını belirlemeniz gerekir. Daha fazla bilgi için, aşağıdaki NikiC tarafından bağlanan SO yayınına bakın.

  4. Kod okunabilirliği.
    PHP'de referanslar oluşturmak hızlı bir şekilde kontrolden çıkar. Eğer bir acemi iseniz ve ne yaptığınızı tam olarak kontrol etmiyorsanız, referanslardan uzak durmak en iyisidir. &Operatör hakkında daha fazla bilgi için şu kılavuza bakın: Referans - Bu sembol PHP'de ne anlama geliyor?
    PHP dilinin bu kısmı hakkında daha fazla bilgi edinmek isteyenler için: PHP Referansları Açıklaması

PHP foreach döngülerinin dahili mantığının @NikiC tarafından çok güzel bir teknik açıklaması:
PHP 'foreach' aslında nasıl çalışır?


Listelenen sorunların yanı sıra , by-referans değişkeninin yinelemeden sonra artık kullanılabilir olmadığından emin olmak için kapatma braketinden unset($value);sonra eklemenizi öneririm foreach. 3v4l.org/2V2AQ
fyrye

15

Kullanın foreach($fields as &$field){- böylece orijinal dizi ile çalışacaksınız.

İşte başvuruyla geçirme konusunda daha fazladır.


@RBA pls yukarıdaki cevaplara bakın - çok daha fazla ayrıntı ve güncellemeleri var - Bir süredir php kullanmadım, bu yüzden bu konuda herhangi bir güncellemeden habersiz
k102

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

Ben referans ile geçmek önermek ne budur


Bu Teknik, orijinal değişkenin değerini değiştirmek için kullanılır. çünkü PHP Pass by Value Technique'i destekliyor. Referans tarafından iletilecek değerin belirtilmesi için değişkenin önüne '&' Karakterini eklemeliyiz
Sagar Kadam

1
O zaman neden hala geri dönüyorsun $fields?
MAZux

Bu önerilen 3'ün en kötü yanıtıdır. Bu cevabı tökezleyen kimseler için, lütfen verileri yerinde değiştirmek ve geri vermek için işlevlerinizi tasarlamayın. Orijinal yazar için: Bu çözümün neden diğerlerinden daha iyi olacağı ya da nasıl çalıştığı hakkında herhangi bir açıklama
yapmadınız

-6

Bunu dene

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

3
Bunu yapma. Kodunuzda en az iki şey yanlış görüyorum: $ alanına atama çalışmıyor ($ fields dizisi bunu yaptığınızda asla değiştirilmez) ve return $ alanı diziyi değil tekil alanı döndürür.
Staplerfahrer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.