Aikido

PHP'de array_filter() işlevini neden array_values() ile sarmalamanız gerekir?

Hata Riski

Kural
Sarmala diziyi filtreleme sonuçları ile array_values()
İşlevler gibi array_filter() değerleri orijinal anahtarları,
ki olabilir hata hatalara çalıştırıldığında kod kod sıralı
sayısal dizini başlayan 'den 0.

Desteklenen diller: PHP

Giriş

PHP'nin array_filter() elemanları filtrelerken, sayısal olarak indekslenmiş dizilerde bile orijinal dizi anahtarlarını korur. Filtreleme işleminden sonra [0 => 'a', 1 => 'b', 2 => 'c'] 1 numaralı dizini silmek için şu sonucu elde edersiniz: [0 => 'a', 2 => 'c'] sayısal tuşlarda bir boşluk olması nedeniyle. 0’dan başlayan sıralı dizinleri bekleyen kod, erişim sırasında hata veriyor $array[1] ya da sürekli indekslerle ilgili varsayımlar temelinde yineleme yapmak. Bu davranış, filtreleme işleminin yeniden indekslenmiş diziler döndürdüğü diğer dillerden gelen geliştiricileri şaşırtmaktadır.

Neden önemli?

Kodun bakım kolaylığı: Sırasız dizi anahtarları, yalnızca belirli koşullarda ortaya çıkan ince hatalara yol açar. Filtrelenmemiş dizilerde sorunsuz çalışan kod, filtreleme işleminden sonra, şu varsayımı yaptığında gizemli bir şekilde hata verir: count($array) - 1 en yüksek geçerli indeks budur. Bu sorunları gidermek zaman kaybına neden olur çünkü temel neden açık değildir; üç elemanlı bir dizi görürsünüz ancak indeks 1 ile ikinci elemana erişemezsiniz.

JSON kodlama sorunları: Ne zaman json_encode() Sıralı olmayan anahtarlara sahip bir dizi olduğunda, PHP bunu dizi yerine bir nesne olarak değerlendirir ve şu sonucu verir: {"0":"a","2":"c"} yerine ["a", "c"]. JSON dizileri bekleyen ön uç kodu, bunun yerine nesneler alır; bu da döngü ve dizi yöntemlerinin çalışmamasına neden olur. PHP dizileri ile JavaScript dizileri arasındaki bu uyumsuzluk, yalnızca filtreleme işlemlerinden sonra ortaya çıkan entegrasyon hatalarına yol açar.

Yineleme ve sayfalandırma hataları: Sonuçları sayfalandıran veya dizileri parçalara ayıran kod, anahtarlar ardışık olmadığında çalışmaz. 0'dan count($array) tanımlanmamış dizinlere erişiyor. Şu şekilde kullanıldığında: array_slice() çünkü sayfalandırma işlemi konumlar üzerinde çalışmasına rağmen orijinal anahtarları döndürdüğü için beklenmedik sonuçlar ortaya çıkar. Bu hatalar, karmaşık veri işleme akışlarında birikerek sorunu daha da ağırlaştırır.

Kod örnekleri

❌ Uygun değil:

function getActiveUsers(array $users): array {
    $activeUsers = array_filter($users, function($user) {
        return $user['status'] === 'active';
    });

    // Bug: assumes index 0 exists and keys are sequential
    $firstActive = $activeUsers[0] ?? null;

    // Bug: JSON encodes as object if keys aren't sequential
    return json_encode($activeUsers);
}

$users = [
    ['id' => 1, 'status' => 'inactive'],
    ['id' => 2, 'status' => 'active'],
    ['id' => 3, 'status' => 'active']
];

// Returns {"1":{"id":2...},"2":{"id":3...}} (object, not array)
getActiveUsers($users);

Neden yanlış: Filtreleme işlemi 0 numaralı elemanı kaldırdıktan sonra, dizide şu anahtarlar kalır: [1, 2] yerine [0, 1], böylece $activeUsers[0] tanımlanmamış. JSON kodlaması, anahtarların sıralı olmaması nedeniyle dizi yerine bir nesne oluşturur; bu da dizi bekleyen ön uç kodlarında hataya yol açar.

✅ Uygunluk:

function getActiveUsers(array $users): string {
    $activeUsers = array_filter($users, function($user) {
        return $user['status'] === 'active';
    });

    // Reindex to sequential keys starting from 0
    $activeUsers = array_values($activeUsers);

    // Now index 0 always exists for non-empty arrays
    $firstActive = $activeUsers[0] ?? null;

    // JSON encodes as proper array: [{"id":2...},{"id":3...}]
    return json_encode($activeUsers);
}

$users = [
    ['id' => 1, 'status' => 'inactive'],
    ['id' => 2, 'status' => 'active'],
    ['id' => 3, 'status' => 'active']
];

// Returns [{"id":2...},{"id":3...}] (array, as expected)
getActiveUsers($users);

Bunun önemi: array_values() Filtrelenmiş diziyi 0'dan başlayan sıralı sayısal anahtarlara göre yeniden indeksler; böylece indeks erişimi öngörülebilir hale gelir ve JSON kodlamasının nesneler yerine diziler üretmesi sağlanır. Bu işlev, hangi öğelerin filtrelenmiş olduğuna bakılmaksızın beklendiği gibi çalışır.

Sonuç

Her zaman sarın array_filter(), array_diff(), ve benzer işlevler ile array_values() Sıralı sayısal dizinlere ihtiyaç duyduğunuzda. Bu, sıralı olmayan anahtarların yol açabileceği fark edilmeyen hataları önler ve JSON kodlamasının nesneler yerine diziler üretmesini sağlar. Performans kaybı, tasarruf edilen hata ayıklama süresine kıyasla ihmal edilebilir düzeydedir.

Sık Sorulan Sorular

Sorularınız mı var?

Hangi PHP dizi işlevleri anahtarları korur ve array_values() işlevini gerektirir?

array_filter(), array_diff(), array_diff_key(), array_intersect() ve array_intersect_key() işlevlerinin tümü orijinal anahtarları korur. Tek bir dizi parametresiyle kullanılan array_map() gibi işlevler de anahtarları korur. Anahtarları koruduğu belirtilen herhangi bir işlevi kullanırken sıralı indekslere ihtiyacınız varsa, bu işlevi array_values() ile sarmalamanız gerekir.

array_values() işlevinin performans açısından herhangi bir etkisi var mı?

Minimal. array_values() işlevi, diziyi yeniden indekslemek için diziyi bir kez tarar; bu işlem O(n) zaman karmaşıklığına sahiptir ancak pratikte çok hızlıdır. Bu maliyet, filtreleme işleminin kendisiyle karşılaştırıldığında ihmal edilebilir düzeydedir ve sıralı olmayan anahtarlardan kaynaklanan üretim sorunlarını gidermeye kıyasla çok daha azdır. Erken optimizasyona karşı her zaman doğruluğu önceliklendirin.

Peki ya dize anahtarlı ilişkisel diziler?

Anahtarları anlamlı dizeler olan ilişkilendirmeli dizilerde array_values() işlevini kullanmayın. Bu işlev, dize anahtarlarınızı sayısal indekslerle değiştirerek önemli bilgilerin kaybolmasına neden olur. Bu kural, yalnızca 0'dan başlayan ardışık anahtarların beklendiği sayısal indeksli diziler için geçerlidir.

Bunun yerine array_splice() veya başka işlevler kullanabilir miyim?

array_splice() işlevi dizinin indeksini otomatik olarak yeniden düzenler, ancak bu işlev ekleme/çıkarma işlemleri için tasarlanmıştır, filtreleme için değil. Filtreleme işlemleri için array_filter() ile birlikte array_values() kullanımı daha net ve dilin kurallarına daha uygundur. Yan etki olarak dizinin indeksinin yeniden düzenlenmesini sağlamak için işlevleri kötüye kullanmak yerine, iş için doğru aracı kullanın.

Kod tabanımda bu sorunu nasıl test edebilirim?

Sonuçlarına sayısal indeksle erişilen, JSON olarak kodlanan veya sıralı anahtarlar bekleyen işlevlere aktarılan array_filter() çağrılarını arayın. Filtrelenen öğelerin dizinin sonunda bulunmadığı verilerle test edin. İlk veya ortadaki öğelerin kaldırılması hatalara neden oluyorsa, array_values() işlevini kullanmanız gerekir.

Ş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.