php sınıf üyeleri başlatmak için en iyi uygulama


10

Benim yapıcılar böyle kod çok var: -

function __construct($params) {

    $this->property = isset($params['property']) ? $params['property'] : default_val;

}

Özellik tanımında varsayılan değeri belirtmek yerine bunu yapmak daha mı iyi? yani public $property = default_val? Bazen varsayılan değer için mantık vardır ve bazı varsayılan değerler diğer özelliklerden alınır, bu yüzden yapıcıda bunu yapıyordum.

Varsayılan değerlerin tüm mantığı ayrılmak için ayarlayıcıları kullanmalı mıyım?

Yanıtlar:


8

Daha önce kendimle bu tür bir felsefi tartışma yaşadım. Bunun görüşe dayalı bir cevap olduğunu fark etsem de çoğu zaman burada duruyorum:

Soruyu cevaplamaya yardımcı olabilecek bir şey, ayarlanmış öznitelikler / dizi üyeleri olabilir veya olmayabilir $ params geçirilmesi olduğunu.

Yıllar boyunca bu sonuca geldim:

Dizilerin geçişinden kaçının.

Neden? İsteğe bağlı geçirilen bağımsız değişkenler için sentinel değerlerini tanımlamanın veya tanımlamanın bir yolu yoktur.

Başka bir deyişle, belirttiğiniz kodla, böyle bir şey yapamazsınız:

function __construct($arg1 = NULL, $arg2 = DEFAULT_VAL) {

    $this->arg1 = $arg1;

    $this->arg2 = $arg2;

}

$ arg1 ve $ arg2 isteğe bağlı bağımsız değişkenlerdir - geçilmediyse sırasıyla NULL ve DEFAULT_VAL değerlerine sahiptir - açıkça kontrol etmeye gerek yoktur.

Belki de bu biraz keyfi gibi görünüyor.

Sanırım başarmaya çalıştığın şeyi elde ediyorum - tonlarca tartışmanın aksine tek bir referansın geçmesi. Bu beni bir sonraki sonuca getiriyor:

"Atomik" değişkenleri (dizeler, tamsayılar, değişmez değerler) geçirmezseniz, nesneleri geçirin.

Burada geçen nesnelere referansla yapıldığı için performans faydaları vardır (diziler kabaca PHP içinde aynı olsa da).

Yani şöyle bir şey yapabilirsiniz:

function __construct(MyAwesomeObject $oArg) {

        $this->oArg = $oArg;

    }

Bu durumda, iletilen nesne bağımsız değişkeninin, muhtemelen varsayılan değerlerin kendileri de olsa "property1", "property2" olduğu garanti edilir.

Ayrıca, burada ipucu yazabilirsiniz ve iyi bir IDE de kod tamamlamayı doğru şekilde otomatik olarak önerecektir.

Ama çabucak bir tavuk ve yumurta şeyimiz olduğunu fark ediyoruz: bir noktada kendilerinin inşa etmesi gereken, geçmiş nesne argümanlarıyla bir nesne inşa ediyorsunuz.

Peki bu bizi nereye bırakıyor? Sonuçta, tüm sınıfların daha iyi bir terim olmamasından ötürü "atom" değişkenlerine (dizeler, yüzen, iki katına, ints, ne demek istediğimi anladığına) damladığı ve denemeye meyilli olduğum sonucuna vardım. bu değişken türleri veya nesnelerle tüm sınıfları oluşturmak - ancak dizileri değil.

Soruna cevap verdim mi? muhtemelen tam olarak değil. Ama umarım biraz üslup da olsa yararlı bir şey gösterdim. Kodun biraz daha temiz, daha okunabilir ve daha az maliyetli olduğunu düşünüyorum.

Şimdi, bu, girdilerinizi sterilize etmemeniz gerektiği anlamına gelmiyor. Bu tamamen başka bir tartışma.

Bu yardımcı olur umarım.


1
İyi bir nokta ve IDE istemleri için çok kullanışlı ama hepsini parametre olarak iletmek için çok fazla nesne özelliği var. Eğer 5 tanesi isteğe bağlı olan 7 argümanınız varsa, bunun gibi şeylerle sonuçlanırsınız new object($param1,-some default value so I can specify the next parameter-, $param3);ve böylece varsayılan değerleriniz birkaç farklı yerde sabit kodlanmış olur
rgvcorley

3

Dizileri bir kurucuya geçirmekten kaçınmaya rağmen, bazen gelen bir dizi değerini işlemek için gerekli buluyorum (örneğin bir yapılandırma dosyasından değerleri okuyan bir sınıf için).

Böyle bir durumda, tam olarak çalıştığımı düşündüğüm ile çalıştığımdan emin olmak için PHP'nin dizi işlevlerinden yararlanacağım:

public function import( array $incoming )
{
  $defaults = array(
      'foo' => DEFAULT_FOO
    , 'bar' => DEFAULT_BAR
    ...
  );

  $values = array_merge($defaults, array_intersect_key($incoming, $defaults));

  ...
}

Bu son satır, array_merge()içindeki tüm değerlerin $defaultskarşılık gelen değerleriyle üzerine yazmak için kullanılır $incoming. Ben de array_intersect_key()ortaya çıkan dizi sınıf / yöntem nasıl işlemek için bilmiyorum herhangi bir ekstra anahtar içermediğinden emin olmak için kullanın .


Merhaba, $ defaultults basit değişkenler yerine bir dizi içeriyorsa davranış nedir?
Pol Dellaiera

@PolDellaiera Şuna bak array_merge_recursive.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.