Aikido

PHP'de dinamik değişken adlarından neden kaçınmalısınız?

Okunabilirlik

Kural
Dinamik değişken adları kullanmaktan
kaçının. Dinamik değişken adları (değişken değişkenler), bakımı
zor kodlara ve beklenmeyen davranışlara yol açabilir. Bunların
kullanımı genellikle bir yazım hatasının sonucudur.

Desteklenen diller: PHP

Giriş

PHP'nin değişken değişkenler (variable variables) özelliği, bir değişkenin değerini diğer bir değişkenin adı olarak kullanmanıza olanak tanır: $$ sözdizimi. Akıllıca bir kısayol gibi görünen bu yapı, hangi değişkenlerin var olduğunu veya ne içerdiğini statik olarak belirleyemediğinizde bir hata ayıklama kabusuna dönüşür. Şunu kullanan kodlar: $$userName bir dizi (array) veya nesne özelliği yerine, IDE'lerin otomatik tamamlama sunmasını, statik analiz araçlarının hataları yakalamasını veya geliştiricilerin uygulama genelinde veri akışını takip etmesini imkansız hale getirir.

Neden önemli?

Kod sürdürülebilirliği: Değişken değişkenler, geliştiricilerin güvendiği tüm araçları devre dışı bırakır. IDE'ler değişken adlarını otomatikleştiremez, kullanımlarını bulamaz veya güvenli bir şekilde yeniden düzenleyemez. Statik analiz araçları tanımlanmamış değişkenleri veya tür uyumsuzluklarını algılayamaz. Değişkenlerin nerede tanımlandığını veya okunduğunu kod tabanında arayamadığınız (grep) için hata ayıklama işlemi çalışma zamanı (runtime) incelemesi gerektirir.

Güvenlik etkileri: Değişken değişken adları kullanıcı girdisinden geldiğinde, saldırganlar güvenlik açısından kritik olanlar dahil olmak üzere rastgele değişkenlerin üzerine yazabilir. Kötü amaçlı bir istek parametresi şunu hedefleyebilir: $$_GET['var'] şunun üzerine yazmak için: $isAdmin, $userIdveya oturum (session) değişkenleri. Bu durum, tespiti zor ve istismarı kolay olan değişken enjeksiyonu (variable injection) açıkları yaratır.

Performans etkisi: Değişken değişkenler, PHP'yi derleme zamanı (compile-time) simge çözünürlüğü yerine çalışma zamanı aramaları yapmaya zorlar. Yorumlayıcı, her erişimde değişken adını dinamik olarak değerlendirmek zorunda kalır ve bu da normal değişkenlerle çalışan optimizasyonları engeller. Diziler ve nesneler, daha iyi performans özellikleri ile benzer işlevsellik sağlar.

Kod örnekleri

❌ Kural dışı:

function processFormData($formType) {
    $userForm = ['name' => '', 'email' => ''];
    $adminForm = ['name' => '', 'email' => '', 'role' => ''];

    $formName = $formType . 'Form';
    $$formName = array_merge($$formName, $_POST);

    if ($$formName['email']) {
        sendEmail($$formName['email']);
    }

    return $$formName;
}

// What variable does this actually use?
processFormData('user');

Neden yanlış: Kod, $userForm veya $adminForm öğesini kullanarak dinamik olarak oluşturur $$formName, hangi değişkenin değiştirildiğini takip etmeyi imkansız hale getirir. Eğer $formType kullanıcı girdisinden geliyorsa, saldırganlar kritik değişkenlerin üzerine yazmak için rastgele değişken adları enjekte edebilir.

✅ Kurallara uygun:

function processFormData(string $formType): array {
    $forms = [
        'user' => ['name' => '', 'email' => ''],
        'admin' => ['name' => '', 'email' => '', 'role' => '']
    ];

    if (!isset($forms[$formType])) {
        throw new InvalidArgumentException('Invalid form type');
    }

    $form = array_merge($forms[$formType], $_POST);

    if (!empty($form['email'])) {
        sendEmail($form['email']);
    }

    return $form;
}

// Clear which data structure is being used
processFormData('user');

Neden önemli?: Kod, bilinen anahtarlara (keys) sahip açık bir dizi kullanır; bu da veri akışını bariz hale getirir ve tüm IDE özelliklerini etkinleştirir. Girdi doğrulama enjeksiyon saldırılarını önler ve statik analiz kodun doğru olduğunu doğrulayabilir.

Sonuç

Değişken değişkenleri diziler, nesneler veya daha iyi bir kod yapısıyla değiştirin. Dinamik anahtar erişimine ihtiyacınız olduğunda dizileri, bilinen özelliklere sahip yapılı veriler için nesneleri kullanın ve yinelenen mantığı uygun soyutlamalarla yeniden düzenleyin. Değişken değişkenler neredeyse her zaman, uygun veri yapıları ile daha net bir şekilde çözülebilecek bir tasarım sorununa işaret eder.

Sık Sorulan Sorular

Sorularınız mı var?

Değişken değişkenlerin meşru bir kullanımı var mı?

Son derece nadir. Şablon motorları ve meta programlama çatıları (frameworks) bazen bunları kullanır, ancak bu durumlarda bile diziler veya özel veri yapıları çok daha uygundur. Değişken değişkenlere ihtiyacınız olduğunu düşünüyorsanız, muhtemelen dinamik anahtarlara sahip bir diziye veya veri akışınızın yeniden tasarlanmasına ihtiyacınız vardır.

Değişkenleri dinamik olarak oluşturan extract() fonksiyonu hakkında ne söylemeli?

Değişken değişkenlerle aynı nedenlerden ötürü extract() fonksiyonundan kaçının. Dizi anahtarlarından dinamik olarak değişkenler oluşturarak statik analizi engeller ve güvenlik riskleri yaratır. extract($data); $key yerine doğrudan dizi erişimini kullanın: $data['key']. Modern PHP kodlarında extract() bir kod kokusu (code smell) olarak değerlendirilmelidir.

Değişken değişkenler kullanan mevcut kodu nasıl yeniden yapılandırabilirim?

Uygulanan deseni belirleyin. Genellikle bu; yapılandırma verileri (diziler kullanın), dinamik özellikler (nesneler veya diziler kullanın) ya da koşullu mantıktır (uygun kontrol yapıları kullanın). Çoğu durumda $$varName ifadesini $config[$varName] ile değiştirin. Tür güvenliğine ve özellik erişimi için IDE desteğine ihtiyaç duyduğunuz durumlarda nesneleri kullanın.

Sabitler için değişken değişkenler kullanmak hakkında ne düşünüyorsunuz?

Hâlâ sorunlu. Sabitlere dinamik olarak erişmeniz gerekiyorsa constant($name) kullanın, ancak bu da bir tasarım sorununa işaret eder. Daha iyi bir yaklaşım: İlgili sabitleri bir sınıfta organize edin ve çalışma zamanı koşullarına göre uygun değeri seçmek için bir dizi veya match ifadesi kullanın.

Değişken değişkenler ad alanı (namespace) çakışmalarına neden olabilir mi?

Evet, özellikle süperkiller ve framework değişkenleriyle birlikte bu mümkündür. $$type = 'value' kullanan kod, beklenmeyen bağlamlarda yanlışlıkla $_GET, $_POST veya $this gibi framework değişkenleri oluşturabilir. Diziler, verilerinin ad alanını doğal olarak ayırır ve bu tür çakışmaları tasarım gereği önler.

Şimdi güvenliğinizi sağlayın

Kodunuzu, bulutunuzu ve çalışma zamanınızı tek bir merkezi sistemde güvenceye alın.
Güvenlik açıklarını otomatik olarak hızla bulun ve düzeltin.

Kredi kartı gerekmez | Tarama sonuçları 32 saniyede.