Günlük Acı
Aşağıdaki kod dizisi, muhtemelen tanıdık bir manzarayı yansıtıyor:
$activeAdmins = array_values(
array_filter(
array_map(fn($u) => $u->refresh(), $users),
fn($u) => $u->isActive() && $u->isAdmin()
)
);Bu kod dizesinde üç temel sorun var:
1. Okuma sırası, yürütme sırasıyla çatışıyor. Kodda array_values ifadesine göz atıyorsunuz ama bu, en son çalışıyor. Bu durum, kodu her zaman ters yönde çözmenize neden oluyor.
2. Türler çöküyor. array_filter, array gibi bir tür dönerken, array_values da benzer bir tür döner. Bir User|Customer birleşimiyle zor bir senaryoya girdiğinizde PHPStan sorun yaşamaya başlıyor.
3. Anahtarlar, PHP dizilerinde tam anlamıyla işlenmez. PHP dizileri, anahtarların üzgün bir taklidi ile çalışır:
$a = ['1' => 'a'];
var_dump(array_keys($a)); // [0 => int(1)], "1" artık bir int
$b = [true => 'x', 1 => 'y'];
count($b); // 1 - true ve 1 çakışıyor
$c = [];
$c[$someUser] = 'admin'; // Fatal error: Illegal offset type
Bu sorunların üzerinden geçerek PHP ile nasıl daha verimli çalışabileceğimize bakalım.
Ne Yaptım
Geliştirdiğim çözüm, üç gerçek tür: List, Set ve Map. Her birinin değiştirilebilir, değiştirilemez ve tembel (lazy) sürümleri mevcut. Bütün yöntemlere akan tam generikler ile yapılan bir yapıdır. Uygulamalar, arayüzlerin arkasında gizlenmiştir, bu nedenle dahili yapıları değiştirmek son derece kolaydır.
Aynı kodu aşağıdaki şekilde yeniden yazabiliriz:
$activeAdmins = listOf($users)
->map(fn(User $u) => $u->refresh())
->filter(fn(User $u) => $u->isActive() && $u->isAdmin());Bu çözüm, kodun okunabilirliğini artırır. Kod, yukarıdan aşağıya doğru okunabilir ve PHPStan, ImmutableList türünü araya sokar. Eğer map() eleman türünü daraltmış olsaydı, bu daralma da propogasyona tabi olacaktı.
Diğer Kütüphanelerden Beklemediğiniz Şeyler
Değiştirilebilir ve değiştirilemez tür ayrımı, bayrak değil, ayrı türlerdir.
MutableList metodu $this dönerken, ImmutableListyeni bir örnek döner ve #[NoDiscard] ile işaretlenir; bu da PHP 8.5’te gerçek bir uyarı haline gelir. “Eklendi” elemanınızın boşluğa atılmasını artık engellemiş olursunuz.
Map görünüm (views) canlı koleksiyonlardır.
$map->keys, $map->values, ve $map->entries gerçek Set ve List örnekleri olarak işleyen, aynı alt yapıyı paylaşan yapılardır. Belleği paylaşır ve tam koleksiyon API’sine sahiptirler. Böylece $map->values->sum() ve $map->keys->sorted() direkt çalışır.
Deneme
composer require noctud/collection
Varsayılan pin (^0.1.1), sizi yalnızca 0.1.x yamanlarına yönlendirir. BC kırılmaları 0.2 sürümü ile gelir ve composer otomatik olarak bunları yüklemez, bu yüzden bu şekilde kilitlemek 0.x döngüsü boyunca güvenceli olacaktır.
Belgeler ve örnekler: https://noctud.dev
GitHub: https://github.com/noctud/collection
This version maintains the structure and important technical components of the original article while translating it for Turkish developers with respect for the important rules provided.
Kaynak: Orijinal Makale


