Fonksiyon iyi PHP parametreleri, ya da kötü bir fikir adında taklit?

4 Cevap php

Ben bu gibi fonksiyonları yazarsanız adında fonksiyon parametreleri PHP taklit edilebilir

function pythonic(array $kwargs)
{
    extract($kwargs);
    // .. rest of the function body
}

// if params are optional or default values are required
function pythonic(array $kwargs = array('name'=>'Jon skeet'))
{
    extract($kwargs);
    // .. rest of the function body
}

Bu yaklaşımın diğer olası olumsuzlukları nelerdir IDE intellisense kaybetme?

Edit:

Ayıklanır değişkenler kapsamını işlev sınırlı olarak Security:, güvenlik, bu durumda olmayan bir konu olması gerekmez mi?

4 Cevap

Ben adında parametrelerini geçmek, ama onları ayıklamak olmadan dizide tutmak için ilişkilendirilebilir bir dizi kullanarak öneririm.

function myFunc(array $args) {
    echo "Hi, " . $args['name'];
    // etc
}

Bu nedenleri bir çift var. Bu işlev baktığımızda, oldukça açıkça ben işlevi geçirilen argümanların birine bahsediyorum görebilirsiniz. Bunları ayıklamak ve fark yoksa extract() (veya sonraki adam) bu "$name" değişkeni nereden geldiğini merak başınızı çizilmeye olacak. Eğer do yerel değişkenleri bağımsız değişkenler ayıklanması biliyorum bile, yine de belli bir dereceye kadar bir tahmin oyunu.

İkincisi, diğer kod args üzerine yazmaz sağlar. Siz diğer kod, örneğin, $baz = 8; tanımlamak bu yüzden sadece, $foo ve $bar adında bir değişkene sahip bekliyordum senin fonksiyonunu yazılmış olabilir. Daha sonra, "baz" adı verilen yeni bir parametre alabilir ama diğer değişkenleri değiştirmek için unutmak için işlevini genişletmek isteyebilirsiniz, bu nedenle olursa olsun argüman geçti alır ne, $baz daima 8'e ayarlanır .

(Bu ayıklanması ya da dizideki bırakarak yöntemleri için aynı ölçüde geçerlidir) çok dizi kullanarak bazı faydaları vardır: adlandırılan her işlevin üstünde bir değişken ayarlayabilirsiniz $defaults:

function myFunc (array $args) {
    $default = array(
        "name" => "John Doe",
        "age" => "30"
    );
    // overwrite all the defaults with the arguments
    $args = array_merge($defaults, $args);
    // you *could* extract($args) here if you want

    echo "Name: " . $args['name'] . ", Age: " . $args['age'];
}

myFunc(array("age" => 25)); // "Name: John Doe, Age: 25"

Hatta gelen $default değeri yok $args hangi tüm öğeleri kaldırmak olabilir. Bildiğiniz bu şekilde tam olarak hangi sahip değişkenler.

İşte bu yapabileceği başka bir yolu.

/**
 * Constructor.
 * 
 * @named string 'algorithm'
 * @named string 'mode'
 * @named string 'key'
 */
public function __construct(array $parameter = array())
{
    $algorithm = 'tripledes';
    $mode = 'ecb';
    $key = null;
    extract($parameter, EXTR_IF_EXISTS);
    //...
}

Bu kurmak ile varsayılan params'ı olsun, sadece zaten değişkenler olarak mevcut olan dizi anahtarları çıkartarak güvenli hale IDE ve EXTR_IF_EXISTS içinde intellisense kaybetmek yok.

(Param bir dizi bir 'isim' endeksi sağlanmazsa, varsayılan değer kaybetti çünkü arada, sağlanan örnek varsayılan değerler yaratmak, iyi değil.)

Iki şeyden biri doğruysa, benim tecrübeme göre, bu yaklaşım gerçekten sadece faydalıdır

  1. Ne olursa olsun hafifletici nedenlerden dolayı, argüman imza büyük. Sadece sağ görünüyor olsa da herhangi bir nedenle değil - - Ben biraz fazla olarak 6 ile gitmek ama ben özgürce bu sayı keyfi olduğunu itiraf.
  2. Lütfen tüm argümanları veya birçok isteğe bağlıdır, ve bazen sadece 5 birinde ya da böyle bir şey için bir değer ayarlamanız gerekir. Yazmak için can sıkıcı someFunc( null, null, null, null, 1 );

Ya bu, sizin için geçerliyse, bir ilişkisel dizi ile adlandırılmış params taklit doğru uygulama olabilir. Kenara ekstresi (veya tamamen kaçınarak) kaçınmak için bilerek hemen diğer olumsuz yanlarını düşünemiyorum.

Yani çoğu zaman bu sorunların hem de üstlenmeden aracılığıyla çözülebilir, söyleniyor.

In my experience, the downside of this method is more code to write. consider something like that:

function someFunc($requiredArg, $arg1 = "default11", $arg2 = "default2") {

Önemli ölçüde daha fazla kod yazmak gerekir Dizideki her şeyi geçerken bu davranışı taklit etmek.

PHP bir sonraki sürümde bu adres için iyi bir fikir olacağını merak ediyorum, belki Pascal veya işlev bağımsız değişkenleri için geçerli VB sözdizimi gibi bir şey var ...

Gerçekten gerektiğinde Neyse, ben sadece tek bir dizi parametre geçirmek - bir çok geliştirme sırasında değiştirmek için muhtemel bir parametre set var fonksiyonları gibi. Bu fonksiyonlar genellikle de çok sayıda parametreleri var.