İçeriğe atla
Üyelik kaydınızı yaparak son yazılan içeriklerden haberdar olun! ×

PHP

  • makale
    10
  • yorum
    0
  • görüntüleme
    849

Named Arguments - PHP


Doğuhan ELMA

69 görünüm

Tıpkı kurucu özellik tanıtımı gibi, isimli argümanlar da PHP 8.0'da yeni bir sözdizimsel eklentidir. Değişkenleri, argüman listesindeki konumları yerine, o fonksiyon içindeki argüman adına göre bir fonksiyona aktarmanıza izin verirler. İşte yerleşik bir PHP işlevi ile bir örnek:

setcookie(
 name: 'test',
 expires: time() + 60 * 60 * 2,
 secure: true,
);

Ve işte bir DTO oluştururken kullanılıyor:

class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

$data = new CustomerData(
    age: $input['age'],
    email: $input['email'],
    name: $input['name'],
);

 

Adlandırılmış argümanlar harika bir yeni özellik ve günlük programlama hayatım üzerinde önemli bir etkisi olacak. Muhtemelen detayları merak ediyorsunuzdur. Ya yanlış bir isim geçerseniz ya da sıralı ve isimli argümanları birleştirirseniz ne olur? Şimdi tüm bu sorulara derinlemesine bakalım.

 

Neden isimlendirilmiş argümanlar?

Bu özellik çok tartışılan bir özellikti. Özellikle geriye dönük uyumluluk açısından eklenmesi konusunda bazı endişeler vardı. Bir paketin bakımını yapıyorsanız ve bir argümanın adını değiştirmeye karar verirseniz, bu artık bir kırılma değişikliği olarak sayılır. Örneğin bir paket tarafından sağlanan bu yöntem imzasını ele alalım:

public function toMediaCollection(
 string $collection,
 string $disk = null
): void { /* … */ }

Bu paketin kullanıcıları adlandırılmış argümanlar kullanacaksa, şöyle bir şey yazarlar Bu:

$media->toMediaCollection(
 collection: 'default',
 disk: 'aws',
);

 

Şimdi, paket sorumlusu olarak $collection adını $collectionName olarak değiştirmek istediğinizi düşünün. Bu, kullanıcılarınız tarafından yazılan kodun bozulacağı anlamına gelir. Bunun teoride bir sorun olduğunu kabul ediyorum, ancak kendim de bir açık kaynak bakımcısı olarak, bu tür değişken adı değişikliklerinin çok nadiren gerçekleştiğini deneyimlerimden biliyorum. Böyle bir değişiklik yaptığımızı hatırladığım tek zaman, zaten kırıcı değişikliklere izin verilen yeni bir ana sürüm üzerinde çalıştığımız içindi. Teorik sorunu kabul etmekle birlikte, bunun pratikte bir sorun olmadığına kesinlikle inanıyorum. Bu tür isim değişiklikleri nadiren gerçekleşir. Ve bir açık kaynak bakımcısı olarak değişken adlarını yönetmekle gerçekten uğraşmak istemeseniz bile, paketinizin README dosyasına bir uyarı ekleyebilirsiniz. Kullanıcılarınıza değişken isimlerinin değişebileceğini ve isimlendirilmiş argümanları kendi riskleri altında kullanmaları gerektiğini söyleyebilirsiniz. Ben sadece bunu aklımda tutmayı ve gelecekte değişken adlarını değiştirirken dikkatli olmam gerektiğini hatırlamayı tercih ediyorum. Önemli bir şey değil. Bu küçük rahatsızlığa rağmen, adlandırılmış argümanların faydalarının çok daha önemli olduğunu söyleyebilirim. Gördüğüm kadarıyla: adlandırılmış argümanlar daha temiz ve daha esnek kod yazmamızı sağlayacak.

Birincisi, adlandırılmış argümanlar varsayılan değerleri atlamamızı sağlar. Çerez örneğine tekrar bir göz atın:

setcookie(
 name: 'test',
 expires: time() + 60 * 60 * 2,
 secure: true,
);

Yöntem imzası aslında aşağıdaki gibidir:

setcookie(
 string $name,
 string $value = '',
 int $expires = 0,
 string $path = '',
 string $domain = '',
 bool $secure = false,
 bool $httponly = false,
) : bool

Adlandırılmış argümanlara sahip örnekte, bir cookie $değeri ayarlamamız gerekmiyordu, ancak bir sona erme süresi ayarlamamız gerekiyordu. Adlandırılmış argümanlar bu yöntem çağrısını biraz daha özlü hale getirdi, çünkü aksi takdirde şöyle görünecekti:

setcookie(
 'test',
 '',
 time() + 60 * 60 * 2,
 '',
 '',
 true
);

Varsayılan değerlere sahip argümanları atlamanın yanı sıra, hangi değişkenin ne işe yaradığını netleştirmenin de faydası vardır, bu özellikle büyük metot imzalarına sahip fonksiyonlarda kullanışlıdır. Çok sayıda argümanın genellikle bir kod kokusu olduğunu söyleyebiliriz; ne olursa olsun onlarla uğraşmak zorundayız. Bu yüzden bunu yapmanın iyi bir yoluna sahip olmak hiç olmamasından daha iyidir.

 

Derinlemesine Adlandırılmış Argümanlar 
Temel bilgileri bir kenara bırakarak adlandırılmış argümanların neler yapabildiğine ve yapamadığına bakalım. Her şeyden önce, isimsiz - sıralı olarak da adlandırılır - argümanlarla birleştirilebilirler. Bu durumda, sıralı argümanlar her zaman önce gelmelidir. Daha önceki DTO örneğimizi ele alalım:

class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

Bu şekilde kurgulayabilirsiniz:

$data = new CustomerData(
 $input['name'],
 age: $input['age'],
 email: $input['email'],
);

Ancak, adlandırılmış bir argümandan sonra sıralı bir argüman olması bir hata oluşturur:

$data = new CustomerData(
 age: $input['age'],
 $input['name'], //hata
 email: $input['email'],
);

 

Daha sonra, dizi yayılımını adlandırılmış argümanlarla birlikte kullanmak mümkündür:

$input = [
 'age' => 25,
 'name' => 'Doğuhan',
 'email' => 'doguhan@elmacademy.net',
];
$data = new CustomerData(...$input);

Bununla birlikte, dizide eksik gerekli girdiler varsa veya adlandırılmış bir bağımsız değişken olarak listelenmemiş bir anahtar varsa, bir hata atılır:

$input = [
 'age' => 25,
 'name' => 'Doğuhan',
 'email' => 'doguhan@elmacademy.net',
 'unknownProperty' => 'Bu yer alamaz.', //hata
];
$data = new CustomerData(...$input);

 

Bir girdi dizisinde adlandırılmış ve sıralı argümanları birleştirmek mümkündür, ancak yalnızca sıralı argümanlar daha önce olduğu gibi aynı kurala uyarsa: önce gelmelidirler!

$input = [
 'Doğuhan',
 'age' => 25,
 'email' => 'doguhan@elmacademy.net',
];
$data = new CustomerData(...$input);

Yine de sıralı ve adlandırılmış argümanları karıştırırken dikkatli olun. Ben şahsen bunların okunabilirliği artırdığını düşünmüyorum.

 

Varyadik Fonksiyonlar 
Variadic fonksiyonlar kullanıyorsanız, adlandırılmış argümanlar anahtar adlarıyla birlikte variadic argümanlar dizisine aktarılacaktır. Aşağıdaki örneği ele alalım:

class CustomerData
{
    public static function new(...$args): self
 {
    return new self(...$args);
 }
public function __construct(
    public string $name,
    public string $email,
    public int $age,
) {}
}
$data = CustomerData::new(
    email: 'doguhan@elmacademy.net',
    age: 25,
    name: 'Doğuhan',
);
// [
// 'age' => 25,
// 'email' => 'doguhan@elmacademy.net',
// 'name' => 'Doğuhan',
// ]

 

Nitelikler 
İşte yine gizemli nitelikler özelliği ile karşı karşıyayız - yakında onları derinlemesine ele alacağız! Şimdilik, bunları oluştururken adlandırılmış argümanları da desteklediklerini söyleyebilirim:

class ProductSubscriber
{
 [ListensTo(event: ProductCreated :class)]
 public function onProductCreated(ProductCreated $event) { /* … */ }
}

 

 

Kayda Değer Diğer Hususlar
Argüman adı olarak bir değişkene sahip olmak mümkün değildir:

$field = 'age';
$data = CustomerData :new(
 $field: 25, //hata
);

 

Ve son olarak, adlandırılmış argümanlar kalıtım sırasında isim değişiklikleriyle pragmatik bir şekilde ilgilenecektir. Bu örneği ele alalım:

interface EventListener {
 public function on($event, $handler);
}
class MyListener implements EventListener
{
 public function on($myEvent, $myHandler)
 {
 // …
 }
}

 

PHP sessizce $event adının $myEvent ve $handler adının $myHandler olarak değiştirilmesine izin verir; ancak, üst öğenin adını kullanarak adlandırılmış argümanlar kullanmaya karar verirseniz, bu bir çalışma zamanı hatasına neden olur:

public function register(EventListener $listener)
{
 $listener >on(
 event: $this >event, //hata
 handler: $this >handler, //hata
 );
}

Bu pragmatik yaklaşım, miras alınan tüm argümanların aynı adı taşıması gereken büyük bir kırılma değişikliğini önlemek için seçilmiştir. Bana mükemmel bir çözüm gibi görünüyor.

0 Yorum


Önerilen Yorumlar

Görüntülenecek yorum yok.

Misafir
Yorum ekle...

×   Zengin metin olarak yapıştırıldı.   Bunun yerine düz metin olarak yapıştır

  Yalnızca 75 emojiye izin verilir.

×   Bağlantınız otomatik olarak gömüldü.   Bunun yerine bağlantı olarak görüntüle

×   Önceki içeriğiniz geri yüklendi.   Düzenleyiciyi temizle

×   Görüntüleri doğrudan yapıştıramazsınız. URL'den resim yükleyin veya ekleyin.

×
×
  • Create New...