noisiv 1
noisiv
Manwe Work 1
Manwe Work
VictoryasHD 1
VictoryasHD
mavzermete 1
mavzermete
lHezarfeNl 1
lHezarfeNl
Bodyguardd 1
Bodyguardd
kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
Reklam vermek için turkmmo@gmail.com

Altın Konu PHP'de in_array() ile Dizi İçinde Değer Aramak

image.jpeg


in_array($needle, $haystack) fonksiyonu, aranan değer dizinin içerisinde mevcutsa true, mevcut değilse false sonucunu döndürür. Tip kontrolünün de yapılmasını istiyorsanız, üçüncü parametre olarak true ekleyerek in_array($needle, $haystack, true) şeklinde kullanmalısınız; güvenlik ve doğruluk açısından bu katı kontrol yöntemi tavsiye edilir.

PHP:
<?php
$roles = ['admin', 'editor', 'viewer'];

var_dump(in_array('editor', $roles));
var_dump(in_array('owner', $roles));

if (in_array('admin', $roles, true)) {
    echo "Show the admin menu\n";
}

in_array() sadece dizi değerlerini denetler. Eğer bir anahtarın (key) varlığını sorgulamak istiyorsanız, array_key_exists() veya isset() fonksiyonlarını kullanmalısınız.

Katı (Strict) Parametre Kullanımı

Üçüncü parametre belirtilmediğinde in_array(), değerleri karşılaştırmadan önce tip dönüşümü yapan == operatörünü kullanır. Ancak bu parametre true olarak ayarlandığında, hem değerin hem de türün aynı olmasını şart koşan === operatörü devreye girer. Özellikle URL, form veya CSV gibi dış kaynaklardan gelen verilerde sayı ve metin karışıklığı yaşanabildiği için bu ayrım kritik önem taşır.

PHP:
<?php
$ids = [1, 2, 3];

var_dump(in_array('2', $ids));          // loose: "2" == 2
var_dump(in_array('2', $ids, true));    // strict: string is not int

$flags = [0, 'off'];
var_dump(in_array(null, $flags));       // null == 0
var_dump(in_array(null, $flags, true));

var_dump(in_array(true, ['yes']));      // 'yes' is truthy, so == true
var_dump(in_array('1e1', ['10']));      // both numeric: 10 == 10

Aşağıdaki tabloda, PHP 8.3 sürümündeki == ve === operatörlerinin farklı değer çiftleri üzerindeki sonuçları yer almaktadır. Seçili modda, aranan değer ile dizideki herhangi bir eleman eşleşip true sonucunu veriyorsa, in_array() fonksiyonu da true yanıtını verir. Kodu çalıştırdığınızda null, true ve sayısal ifadeler içeren satırlardaki farkları gözlemleyebilirsiniz.

in_array'de Gevşek (==) ve Katı (===) Eşleşmeler

$a == $btruefalsenull01"0""1""""abc""10""1e1"10[]
truetruefalsefalsefalsetruefalsetruefalsetruetruetruetruefalse
falsefalsetruetruetruefalsetruefalsetruefalsefalsefalsefalsetrue
nullfalsetruetruetruefalsefalsefalsetruefalsefalsefalsefalsetrue
0falsetruetruetruefalsetruefalsefalsefalsefalsefalsefalsefalse
1truefalsefalsefalsetruefalsetruefalsefalsefalsefalsefalsefalse
"0"falsetruefalsetruefalsetruefalsefalsefalsefalsefalsefalsefalse
"1"truefalsefalsefalsetruefalsetruefalsefalsefalsefalsefalsefalse
""falsetruetruefalsefalsefalsefalsetruefalsefalsefalsefalsefalse
"abc"truefalsefalsefalsefalsefalsefalsefalsetruefalsefalsefalsefalse
"10"truefalsefalsefalsefalsefalsefalsefalsefalsetruetruetruefalse
"1e1"truefalsefalsefalsefalsefalsefalsefalsefalsetruetruetruefalse
10truefalsefalsefalsefalsefalsefalsefalsefalsetruetruetruefalse
[]falsetruetruefalsefalsefalsefalsefalsefalsefalsefalsefalsetrue

PHP 8 ile birlikte önemli bir kural değişti: Artık sayısal olmayan dizgeler 0 değerine eşit kabul edilmiyor. Bu nedenle, PHP 7'de true dönen in_array('abc', [0]) ifadesi artık false sonucunu verir. Eski sürümlere göre yazılmış kodlar bazen bu davranışa dayandığı için, tip dönüşümlerine güvenmek yerine katı kontrol kullanmak daha güvenlidir. Karşılaştırma operatörleri sayfası bu konuyu detaylandırmaktadır.

Büyük/Küçük Harf Duyarlılığını Giderme

in_array() fonksiyonu metinleri birebir karşılaştırır, dolayısıyla 'PHP' ile 'php' farklı değerler olarak algılanır. Aramayı büyük/küçük harf fark etmeksizin yapmak isterseniz, hem aranan kelimeyi hem de dizideki öğeleri küçük harfe dönüştürmelisiniz. Bu işlem için Latin dışı ve aksanlı karakterleri de destekleyen mb_strtolower() fonksiyonu kullanılabilir.

PHP:
<?php
$allowed = ['jpg', 'PNG', 'Gif'];
$ext = 'png';

var_dump(in_array($ext, $allowed, true));

$lower = array_map('strtolower', $allowed);
var_dump(in_array(strtolower($ext), $lower, true));

$cities = ['München', 'Zürich'];
var_dump(in_array('ZÜRICH', $cities, true));
var_dump(in_array(mb_strtolower('ZÜRICH'), array_map('mb_strtolower', $cities), true));

Birden Fazla Değeri Aynı Anda Sorgulama

in_array() tek seferde sadece bir değer kontrol edebilir. Eğer birden fazla değerin varlığını denetlemek istiyorsanız, dizileri küme mantığıyla karşılaştırmanız gerekir: array_diff() fonksiyonu dizide bulunmayan değerleri döndürür (sonuç boşsa tüm değerler mevcut demektir); array_intersect() ise ortak olan değerleri listeler.

PHP:
<?php
$skills = ['php', 'sql', 'git', 'docker'];

$required = ['php', 'git'];
$hasAll = array_diff($required, $skills) === [];
var_dump($hasAll);

$wanted = ['rust', 'sql'];
$hasAny = array_intersect($wanted, $skills) !== [];
var_dump($hasAny);

print_r(array_diff(['php', 'go'], $skills));   // what is missing

array_diff() ve array_intersect() fonksiyonları değerleri metin olarak karşılaştırdığı için 1 ile '1' değerlerini eşit kabul eder.

Çok Boyutlu Dizilerde in_array Kullanımı

in_array(), iç içe geçmiş dizilerin derinliklerinde arama yapmaz. Alt dizilerdeki belirli bir sütunda arama yapmak için önce array_column() ile ilgili alanı tek boyutlu bir listeye indirgemeli, ardından bu liste üzerinde arama yapmalısınız.

PHP:
<?php
$users = [
    ['id' => 1, 'email' => 'ada@example.com'],
    ['id' => 2, 'email' => 'linus@example.com'],
];

var_dump(in_array('ada@example.com', $users, true));    // compares whole rows

$emails = array_column($users, 'email');
var_dump(in_array('ada@example.com', $emails, true));

var_dump(in_array(['id' => 2, 'email' => 'linus@example.com'], $users, true));

Son satırdaki örnek, aranan değerin kendisi bir dizi olduğunda; ancak aynı anahtarlara, değerlere ve sıralamaya sahip tamamen özdeş bir satırla eşleşeceğini göstermektedir.

in_array, array_search ve isset Karşılaştırması

Bu üç yöntem de temel olarak "değer orada mı?" sorusunu yanıtlar, ancak dönüş değerleri ve performansları farklıdır:

ÇağrıDöndürürBüyük bir dizide hız
in_array($v, $arr, true)true veya falseher elemanı tarar
array_search($v, $arr, true)anahtar veya falseher elemanı tarar
isset($set[$v])true veya falsetek bir hash araması

Eğer değerin sadece var olup olmadığını değil, hangi konumda (indis) olduğunu öğrenmek istiyorsanız array_search() kullanmalısınız. Çok büyük listelerde sık sık sorgulama yapacaksanız, diziyi bir kez array_flip() ile ters çevirerek değerleri anahtar haline getirmek ve ardından isset() kullanmak çok daha hızlıdır.

PHP:
<?php
$banned = [];
for ($i = 0; $i < 100000; $i++) {
    $banned[] = "user$i";
}
$checks = ['user99999', 'guest', 'user5'];

$start = hrtime(true);
for ($n = 0; $n < 200; $n++) {
    foreach ($checks as $name) {
        in_array($name, $banned, true);
    }
}
printf("in_array: %.1f ms\n", (hrtime(true) - $start) / 1e6);

$set = array_flip($banned);        // values become keys, done once
$start = hrtime(true);
for ($n = 0; $n < 200; $n++) {
    foreach ($checks as $name) {
        isset($set[$name]);
    }
}
printf("isset:    %.1f ms\n", (hrtime(true) - $start) / 1e6);

var_dump(isset($set['user5']), isset($set['guest']));

Çalıştırma süreleri ortama göre değişebilir ancak temel performans farkı sabittir: isset() araması her zaman hızlıyken, in_array() listenin boyutu arttıkça yavaşlar. array_flip() yalnızca tam sayı ve dizge değerlerle çalışır ve tekrarlayan değerler tek bir anahtara indirgenir; ancak bu durum üyelik kontrolü için bir sorun teşkil etmez.
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst