İsteğe bağlı argümanlar PHP adında?

14 Cevap php

Eğer (Python gibi) belirtmek istemiyorum olanları atlama, çağırırken bir adlandırılmış bağlı parametreyi belirtmek için PHP 4/5 mümkün mü?

Gibi bir şey:

function foo($a,$b='', $c='') {
    // whatever
}


foo("hello", $c="bar"); // we want $b as the default, but specify $c

Teşekkürler

14 Cevap

Hayır, bu mümkün değil: Eğer üçüncü parametre geçmek istiyorsanız, ikinci bir geçmek zorunda. Ve parametreler da mümkün değildir adlandırılmış.


A "solution" would be to use only one parameter, an array, and always pass it... But don't always define everything in it.

Örneğin:

function foo($params) {
    var_dump($params);
}

Ve bu şekilde çağırıyor:

foo(array(
    'a' => 'hello',
));

foo(array(
    'a' => 'hello',
    'c' => 'glop',
));

foo(array(
    'a' => 'hello',
    'test' => 'another one',
));

Bu çıktıyı alırsınız:

array
  'a' => string 'hello' (length=5)

array
  'a' => string 'hello' (length=5)
  'c' => string 'glop' (length=4)

array
  'a' => string 'hello' (length=5)
  'test' => string 'another one' (length=11)

Ama gerçekten bu çözüm sevmiyorum:

  • Sen PHPDoc kaybedersiniz
  • IDE artık herhangi bir ipucu sağlamak mümkün olmayacaktır ... Hangi kötü

Yani sadece çok özel durumlarda bu ile gitmek istiyorum - optionnal parametreleri sürü fonksiyonlar için, örneğin ...

PHP ile, argümanların sırası önemli şeydir. Sen yersiz belirli bir bağımsız değişken belirtmek değil, ancak bunun yerine, sürece bir NULL değeri olan sizin işlevi değerini umursamıyorum gibi, bir null geçirerek argümanlar atlayabilirsiniz.

foo("hello", NULL, "bar");

Hayır, PHP adıyla argümanlar geçemez.

Eğer argümanlar ve bunların tüm işlev yerine bir dizi argümanı kabul yapımında düşünebilirsiniz varsayılan değerlere sahip bir sürü alır bir işlevi varsa:

function test (array $args) {
    $defaults = array('a' => '', 'b' => '', 'c' => '');
    $args = array_merge($defaults, array_intersect_key($args, $defaults));

    list($a, $b, $c) = array_values($args);
    // an alternative to list(): extract($args);

    // you can now use $a, $b, $c       
}

See it in action .

Hayır, öyle değil.

Eğer biraz yapabileceğiniz tek yolu adında tuşları ve ne ile değil dizileri kullanarak gereğidir.

Sen PHPDoc ve bir dizi örneğin bir nesne geçirerek yerine göre varsayılan ayarlamak için yeteneği tutabilirsiniz

class FooOptions {
  $opt1 = 'x';
  $opt2 = 'y';
  /* etc */
};

Bu da isterseniz, sizin işlev çağrısında sıkı bir yazım denetimi yapmanıza olanak sağlar:

function foo (FooOptions $opts) {
  ...
}

Tabii ki, FooOptions nesneyi kurma ekstra ayrıntı ile bunun için ödeme olabilir. Hiçbir tamamen ücretsiz binmek var ne yazık ki.

Tam olarak hoş değil, ama hile yok, bazı diyebilirsiniz.

class NamedArguments {

    static function init($args) {
        $assoc = reset($args);
        if (is_array($assoc)) {
            $diff = array_diff(array_keys($assoc), array_keys($args));
            if (empty($diff)) return $assoc;
            trigger_error('Invalid parameters: '.join(',',$diff), E_USER_ERROR);
        }
        return array();
    }

}

class Test {

    public static function foobar($required, $optional1 = '', $optional2 = '') {
        extract(NamedArguments::init(get_defined_vars()));
        printf("required: %s, optional1: %s, optional2: %s\n", $required, $optional1, $optional2);
    }

}

Test::foobar("required", "optional1", "optional2");
Test::foobar(array(
    'required' => 'required', 
    'optional1' => 'optional1', 
    'optional2' => 'optional2'
    ));

İşte kullanarak oldum buydu. Bir işlev tanımı opsiyonel adlandırılmış değişkenleri belirten isteğe bağlı bir dizi argüman alır:

function func($arg, $options = Array()) {
  $defaults = Array('foo' => 1.0,
                    'bar' => FALSE);
  $options = array_merge($default, $options);

  // Normal function body here.  Use $options['foo'] and
  // $options['bar'] to fetch named parameter values.
  ...
}

Normalde herhangi adında bir argüman olmadan çağırabilirsiniz:

func("xyzzy")

İsteğe bağlı adlandırılmış bağımsız değişkeni belirtmek için, isteğe bağlı dizide geçmek:

func("xyzzy", Array('foo' => 5.7))

Hayır değil. Eğer kullanabilirsiniz bunun için birkaç alternatif vardır.

test(null,null,"hello")

Ya da bir dizi pass:

test(array('c' => "hello"));

Ardından, işlevi olabilir:

function test($array) { 
    $c = isset($array[c]) ? $array[c] : '';
}

Arasında veya bir işlev eklemek, ama bu tavsiye etmem:

function ctest($c) { test('','',$c); }

Try function test ($a="",$b="",&$c=""){}

Koymak & önce $c

I dont think so... If you need to call, for example, the substr function, that has 3 params, and want to set the $length without set the $start, you'll be forced to do so.

substr($str,0,10);

Bu geçersiz kılmak için güzel bir yol, her zaman arrays parametreleri için kullanmaktır

Simple answer. No you can't.
You could try getting around it by passing in an object/array or using some other Dependency injection patterns.

Ayrıca, daha kesin olduğu gibi is_null kullanarak kendi varlığını sınamak için oldukça boş dizeleri daha boş değerlere kullanmayı deneyin ()

örneğin:

function test ($a=null,$b=null,$c=null){
 if (is_null($a) {
  //do something about $a
 }
 if (is_null($b) {
  //do something about $b
 }
 if (is_null($c) {
  //do something about $c
 }
}

Bu aramak için:

test(null,null,"Hello");

Çok kısa, bazen evet, yansıma ve yazdığınız değişkenleri kullanarak. Ancak bu sonra ne muhtemelen değildir düşünüyorum.

Senin soruna daha iyi bir çözüm fonksiyonları fonksiyon içinde eksik bir kolu olarak 3 argümanlar geçmek muhtemelen kendinizi

<?php  
   function test(array $params)
   {
     //Check for nulls etc etc
     $a = $params['a'];
     $b = $params['b'];
     ...etc etc
   }

Bunu python şekilde yapamaz. Anway, bir ilişkisel dizi geçmek ve kendi adıyla dizi girdilerini kullanmak daha olabilir:

function test ($args=array('a'=>'','b'=>'','c'=>''))
{
    // do something
}

test(array('c'=>'Hello'));

Bu yazarak azaltmak değil, ama en azından daha açıklayıcı bulunuyor, çağrı argümanların isimleri görülebilir ve okunabilir olması.

Normalde ama orada bir PHP işlevi adlandırılmış argümanların yollar bir sürü düşünemiyorum. Şahsen ben dizileri kullanarak tanımı röle ve sadece ben geçmesi gerekir ne diyoruz:

class Test{
    public $a  = false;
    private $b = false;
    public $c  = false;
    public $d  = false;
    public $e  = false;
    public function _factory(){
        $args    = func_get_args();
        $args    = $args[0];
        $this->a = array_key_exists("a",$args) ? $args["a"] : 0;
        $this->b = array_key_exists("b",$args) ? $args["b"] : 0;
        $this->c = array_key_exists("c",$args) ? $args["c"] : 0;
        $this->d = array_key_exists("d",$args) ? $args["d"] : 0;
        $this->e = array_key_exists("e",$args) ? $args["e"] : 0;
    }
    public function show(){
        var_dump($this);
    }
}


$test = new Test();
$args["c"]=999;
$test->_factory($args);
$test->show();

live example here: http://sandbox.onlinephpfunctions.com/code/d7f27c6e504737482d396cbd6cdf1cc118e8c1ff

Ben 10 argümanları geçmek zorunda, ve 3 tanesi gerçekten ihtiyacım veri iseniz gibi işlev şeye geçmesine BİLE SMART DEĞİLDİR

return myfunction(false,false,10,false,false,"date",false,false,false,"desc");

Yaklaşımı ile ben kurulum bir diziye 10 argümanların herhangi can veriyorum,:

$arr['count']=10;
$arr['type']="date";
$arr['order']="desc";
return myfunction($arr);

Ben daha detaylı olarak bu süreci açıklayan blogumda bir yazı var.

http://www.tbogard.com/2013/03/07/passing-named-arguments-to-a-function-in-php