- Konu sahibi
- #1
“Undefined array key” hatası, kodun dizide bulunmayan bir anahtarı okumaya çalıştığını gösterir. Çözüm, anahtarı kullanmadan önce gerçekten mevcut olup olmadığını kontrol etmek veya yoksa kullanılacak varsayılan değeri belirlemektir. PHP sürümüne göre uyarı ya da bildirim biçiminde görülebilen bu durum çoğunlukla form verilerinde, URL parametrelerinde ve dış kaynaktan alınan dizilerde ortaya çıkar.
Aşağıdaki örnekte kod,
Bu kod çalıştırıldığında
Hangi yöntemin kullanılacağı, anahtar bulunmadığında uygulamanın ne yapması gerektiğine bağlıdır. Anahtar zorunluysa hatayı gizlemek yerine eksik veriyi reddetmek; isteğe bağlıysa varsayılan değer kullanmak gerekir.
Anahtarın varlığını
Anahtarın dizide bulunup bulunmadığını kontrol etmek için
Bu yöntemde anahtar mevcutsa değer okunur, yoksa
Değer
Anahtarın hem mevcut olmasını hem de
Varsayılan değer vermek için
Anahtar bulunmadığında uygulamanın kullanacağı makul bir varsayılan değer varsa null birleştirme operatörü (
Bu örnekte
İsteğe bağlı bir alan için varsayılan değer belirleyin:
Alan zorunluysa eksik veriyi sessizce boş kabul etmek yerine açıkça doğrulamak daha doğrudur:
Burada
Aşağıdaki ayrım, hatayı geçici olarak saklamak yerine doğru davranışı seçmenize yardımcı olur.
Bu seçim, hatanın yalnızca görünmesini engellemekten daha önemlidir. Örneğin kullanıcı kimliği zorunlu olduğu hâlde
Önce hata mesajındaki anahtar adını belirleyin. Örneğin mesaj
Hatanın üstünü
Bu yaklaşım eksik anahtarı düzeltmez; yalnızca uyarıyı bastırır ve gerçek veri sorunlarının fark edilmesini zorlaştırır. Benzer şekilde, tüm hata raporlamasını kapatmak da uygulamanın hatayı üretmesine neden olan veri akışını düzeltmez.
Doğru yaklaşım, önce anahtarın zorunlu mu isteğe bağlı mı olduğunu belirlemek, ardından
Hatanın nedeni
Aşağıdaki örnekte kod,
email anahtarının dizide bulunduğunu varsayar:
PHP:
<?php
$data = [
'name' => 'Ayşe'
];
echo $data['email'];
Bu kod çalıştırıldığında
email anahtarı tanımlı olmadığı için “Undefined array key "email"” benzeri bir uyarı oluşur. Buradaki sorun dizinin kendisinin tanımsız olması değil, dizinin içinde istenen anahtarın bulunmamasıdır.En güvenli çözüm yöntemleri
Hangi yöntemin kullanılacağı, anahtar bulunmadığında uygulamanın ne yapması gerektiğine bağlıdır. Anahtar zorunluysa hatayı gizlemek yerine eksik veriyi reddetmek; isteğe bağlıysa varsayılan değer kullanmak gerekir.
Anahtarın varlığını array_key_exists() ile kontrol etmek
Anahtarın dizide bulunup bulunmadığını kontrol etmek için
array_key_exists() kullanılabilir:
PHP:
<?php
$data = [
'name' => 'Ayşe'
];
if (array_key_exists('email', $data)) {
echo $data['email'];
} else {
echo 'E-posta adresi girilmedi.';
}
Bu yöntemde anahtar mevcutsa değer okunur, yoksa
else bloğu çalışır. array_key_exists() anahtarın değerinin null olmasına rağmen anahtarın mevcut olduğunu kabul eder. Bu ayrım önemliyse isset() yerine bu işlev kullanılmalıdır.Değer null değilse isset() kullanmak
Anahtarın hem mevcut olmasını hem de
null olmamasını istiyorsanız isset() daha kısa bir çözümdür:
PHP:
<?php
$data = [
'name' => 'Ayşe'
];
if (isset($data['email'])) {
echo $data['email'];
} else {
echo 'E-posta adresi yok.';
}
isset() anahtar bulunmadığında veya değer null olduğunda false döndürür. Ancak değer 0, false veya boş dizeyse bunlar null olmadığı için isset() sonucu true olur.Varsayılan değer vermek için ?? kullanmak
Anahtar bulunmadığında uygulamanın kullanacağı makul bir varsayılan değer varsa null birleştirme operatörü (
??) en pratik çözümdür:
PHP:
<?php
$data = [
'name' => 'Ayşe'
];
$email = $data['email'] ?? 'E-posta belirtilmedi';
echo $email;
Bu örnekte
email anahtarı yoksa $email değişkenine E-posta belirtilmedi atanır ve uyarı oluşmaz. Anahtar mevcut fakat değeri null ise yine varsayılan değer kullanılır.Form verilerinde doğru kontrolü yapmak
$_POST, $_GET ve benzeri süper global dizilerde anahtarın her istekte gönderileceği varsayılmamalıdır. Örneğin aşağıdaki kullanım, form alanı gönderilmediğinde hata üretebilir:
PHP:
<?php
$name = $_POST['name'];
echo htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
İsteğe bağlı bir alan için varsayılan değer belirleyin:
PHP:
<?php
$name = $_POST['name'] ?? '';
echo htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
Alan zorunluysa eksik veriyi sessizce boş kabul etmek yerine açıkça doğrulamak daha doğrudur:
PHP:
<?php
$name = trim($_POST['name'] ?? '');
if ($name === '') {
http_response_code(400);
exit('Ad alanı zorunludur.');
}
echo htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
Burada
?? '' eksik anahtar nedeniyle oluşacak uyarıyı önler; ardından trim() ve koşul, alanın gerçekten dolu olup olmadığını kontrol eder. Yalnızca uyarıyı bastırmak, form alanının zorunlu olup olmadığını doğrulamaz.Hangi yöntemi ne zaman kullanmalısınız?
Aşağıdaki ayrım, hatayı geçici olarak saklamak yerine doğru davranışı seçmenize yardımcı olur.
| Durum | Uygun yaklaşım |
|---|---|
| Anahtar isteğe bağlı ve eksikse bir değer kullanılabilir | $array['key'] ?? $default |
Anahtarın varlığı önemli, değer null olabilir | array_key_exists() |
Anahtarın değeri null olmamalı | isset() |
| Anahtar zorunlu kullanıcı veya API verisi içeriyor | Önce varsayılan değerle alıp sonra doğrulama ve hata yanıtı uygulayın |
$_GET['user_id'] ?? 0 kullanmak uyarıyı kaldırır; fakat geçersiz bir 0 değeriyle yanlış sorgu çalıştırılmasına neden olabilir. Zorunlu alanlarda eksik değeri açıkça reddedin.Hata devam ederse nasıl bulunur?
Önce hata mesajındaki anahtar adını belirleyin. Örneğin mesaj
Undefined array key "category" diyorsa ilgili satırda $data['category'], $_POST['category'] veya benzeri bir erişim aranmalıdır. Ardından anahtarın gerçekten hangi noktada oluşturulması gerektiğini kontrol edin:- Dizinin oluştuğu yerde
categoryanahtarının eklenip eklenmediğini kontrol edin. - Form kullanılıyorsa HTML alanının
name="category"değerinin PHP kodundaki anahtarla aynı olduğundan emin olun. - URL parametresi bekleniyorsa isteğin gerçekten
categoryparametresini içerip içermediğini kontrol edin. - Veritabanı sonucu kullanılıyorsa sorgunun döndürdüğü sütun adını ve kullanılan dizi biçimini doğrulayın.
- Geçici hata ayıklama sırasında
var_dump($data);veyavar_export($data);ile dizinin gerçek yapısını inceleyin; hassas verileri canlı ortamda göstermeyin ve tanılama çıktısını iş bittikten sonra kaldırın.
var_dump() çıktısında anahtar category_id olarak görünüyorsa kodda $data['category'] kullanmak yerine gerçek veri yapısına göre karar verilmelidir. Anahtarı rastgele değiştirmek doğru çözüm değildir; veri kaynağının hangi adı gönderdiği ve uygulamanın hangi adı beklediği birlikte eşleştirilmelidir.Kaçınılması gereken çözümler
Hatanın üstünü
@ operatörüyle kapatmak önerilmez:
PHP:
<?php
$email = @$data['email'];
Bu yaklaşım eksik anahtarı düzeltmez; yalnızca uyarıyı bastırır ve gerçek veri sorunlarının fark edilmesini zorlaştırır. Benzer şekilde, tüm hata raporlamasını kapatmak da uygulamanın hatayı üretmesine neden olan veri akışını düzeltmez.
Doğru yaklaşım, önce anahtarın zorunlu mu isteğe bağlı mı olduğunu belirlemek, ardından
??, isset() veya array_key_exists() arasından buna uygun olanı seçmektir. Hata form ya da dış istek verisinden kaynaklanıyorsa eksik değeri aldıktan sonra ayrıca doğrulama yapın; böylece hem “Undefined array key” uyarısı giderilir hem de uygulama eksik veriyi doğru biçimde işler.