Benim PHP fonksiyonları bir dizi argümanı kabul etmeli ya da ben açıkça argümanları talep etmelisiniz?

7 Cevap php

Bir PHP web uygulaması üzerinde çalışıyorum, ben olası iki şekilde tanımlanabilir fonksiyonları görmek.

Yaklaşım 1:

function myfunc($arg1, $arg2, $arg3)

Yaklaşım 2:

// where $array_params has the structure array('arg1'=>$val1, 'arg2'=>$val2, 'arg3'=>$val3)
function myfunc($array_params)

Ne zaman başka bir yere bir yaklaşım kullanmanız gerekir? Bu sistem gereksinimleri sürekli değişiyor ve bu nedenle MyFunc için argüman sayısı sürekli değişiyor ise, yaklaşım 1 bakım çok gerekebilir gibi görünüyor.

7 Cevap

Sistem sık sık dizinlenmiş bir dizi kullanarak en iyi çözüm olduğunu değişiyor, ben bu endişeler az olduğunu söyleyebilirim. :-)

Genel işlevler / yöntem çok fazla argüman (maksimum olarak 5 artı ya da eksi 2) almamalıdır ve ben size adlı (ve ideal type hinted) argümanları kullanarak sopa gerektiğini söylemek istiyorum. (Isteğe bağlı verilerin büyük bir miktar var ise bir argüman endeksli dizisi sadece gerçekten mantıklı - iyi bir örnek konfigürasyon bilgisi olmak.)

@ Pekka dediği gibi, argümanlar dizisini geçirerek, belge için bir ağrı olarak yükümlü olduğu ve bu nedenle diğer insanlar / kendiniz için 'n' aylarda korumak için.

Update-ette...

Bu arada, sık sık ayrıntı oldukça biraz Code Complete inceler gibi konular söz - bu son derece tavsiye ederim harika bir cilt bulunuyor.

Bir params dizisi (diğer dillerde "adlı argümanlar" "denilen bir vekil) kullanarak harika - Ben kendim kullanmak istiyorum - ama oldukça büyük bir dezavantajı vardır: Argümanlar standart Phpdoc notasyonu yolu kullanarak belgelendirilebilir değildir, ve dolayısıyla, IDE bir işlevin veya yöntemin adını yazdığınızda size ipuçları vermek mümkün olmayacaktır.

Ben işlevi varsayılan bir dizi geçersiz kılmak istediğiniz zaman yararlı olduğu argümanların bir optional dizi kullanarak bulabilirsiniz. Farklı konfigürasyon seçenekleri bir yeri vardır ya da bilgi için sadece bir aptal kapsayıcı bir nesne oluşturarak zaman yararlı olabilir. Bu benim Ruby dünyanın çoğunlukla aldı şeydir.

Benim web sayfasında bir video için bir kapsayıcı yapılandırmak istiyorsanız bir örnek olabilir:

function buildVideoPlayer($file, $options = array())
{
  $defaults = array(
    'showAds' => true,
    'allowFullScreen' = true,
    'showPlaybar' = true
  );

 $config = array_merge($defaults, $options);

 if ($config['showAds']) { .. }
}

$this->buildVideoPlayer($url, array('showAds' => false));

$ Seçenekler başlangıç ​​değeri bu kadar isteğe bağlı tüm sağlayarak, boş bir dizi olduğuna dikkat edin.

Ayrıca, bu yöntemle başvururken bu yüzden sürekli is_array() çek veya isset() gerek yok biz $ seçenekleri her zaman dizi olacağını biliyorum, ve biz bu tuşlar varsayılan biliyorum argüman.

İlk yaklaşım ile gerekli tüm parametreleri sağlamak için fonksiyon kullanıcıları zorluyor. İkinci yolu size ihtiyacınız var emin olamaz. Ben ilk yaklaşımı tercih ediyor.

Eğer geçen konum parametreler birlikte gruplandırılmış olabilir eğer mantıksal bir parametre nesnesi (Refactoring, Martin Fowler, P295) kullanarak düşünmek verebilecek, bu şekilde daha fazla parametre eklemek gerekir eğer sadece daha ekleyebilirsiniz Lütfen parametre sınıf alanları ve mevcut yöntemleri kırmak olmaz.

Her şekilde artıları ve eksileri vardır.

  • Bu değiştirmek mümkün değildir, ve sadece birkaç bağımsız değişkenleri basit bir fonksiyon varsa, o zaman ben açıkça onları devlet istiyorsunuz.

  • Fonksiyon argümanları çok sayıda, ya da gelecekte bir çok değişme olasılığı varsa, o zaman ben tuşları ile argümanlar dizisini geçmek ve kullanmak istiyorsunuz. Eğer sadece sık sık argümanları bazı geçmesi gerekiyor fonksiyonu varsa bu da faydalı olur.

Ben bir form alanı oluşturulmuş bir işlevi olsaydı argümanları üzerinde bir dizi seçsin zaman bir örnek, bir örnek olacaktır. Ben isteyebilirsiniz olası argümanlar:

  • Tip
  • Değer
  • sınıf
  • Kimlik
  • stil
  • seçenekleri
  • is_required

ve ben sadece bu birkaç geçmesi gerekebilir. Bir alan = metin yazın ise, örneğin, ben seçenekleri ihtiyacım yok. Ben her zaman bir sınıf ya da varsayılan bir değer gerek olmayabilir. Bu şekilde bir ton argümanlar ile bir fonksiyon imzası olan ve boş her zaman geçmeden, argümanlar çeşitli kombinasyonlarda geçmek daha kolaydır. HTML 5 artık standart çok uzun yıllar olduğunda da, ben gibi otomatik tamamlama ya da kapatmak gibi ek olası argümanlar, eklemek isteyebilirsiniz.

Ben bu eski bir yazı olduğunu biliyorum, ama benim yaklaşım paylaşmak istiyorum. Değişkenler mantıksal bir tür bağlıysa, bir sınıfta grup onları can ve işlevine onları bir nesne geçmek. örneğin:

      class user{
           public $id;
           public $name;
           public $address;
           ...
      }

ve çağrı:

      $user = new user();
      $user->id = ...
      ...

      callFunctions($user);

Yeni bir parametre gerekiyorsa sadece sınıfta ekleyebilirsiniz ve fonksiyon imza değiştirmeniz gerekmez.