Nesneler için yeni bir nesne, call_user_func_array oluştururken PHP parametreleri geçirerek

5 Cevap

Ben dinamik olarak bir PHP nesnesi oluşturmak istiyoruz, ve parametreler isteğe bağlı olacaktır.

Örneğin, yerine bunu yapmanın:

$test = new Obj($param);

Böyle bir şey (kurgusal yeni ob oluşturmak) yapmak istiyorum:

$test = create_new_obj('Obj', $param);

Php böyle bir işlevi var mı? Call_user_func_array benzer bir şey, ama nesnenin yerine.

5 Cevap

Bazı kurucular argümanlar farklı bir sayı alabilir yana, bu şekilde kolayca ağırlayacak.

$r = new ReflectionClass($strClassName);
$foo = $r->newInstanceArgs($arrayOfConstructorArgs);

Örneğin, Araba yapıcı 3 Değiştirgeleri aldı

$carObj = new Car($color, $engine, $wheels);

O zaman

$strClassName = 'Car';
$arrayOfConstructorArgs = array($color, $engine, $wheels);
$r = new ReflectionClass($strClassName);
$carObj = $r->newInstanceArgs($arrayOfConstructorArgs);

http://php.net/manual/en/class.reflectionclass.php
http://php.net/manual/en/reflectionclass.newinstanceargs.php

Dinamik sürece sınıf adını bildiğiniz gibi bir nesne oluşturabilirsiniz:

$objName = 'myClass';
$test = new $objName($param);

Kolayca sizin inşaat mantığının bir gereği olarak, bir __construct() function yanı default arguments almak için tanımlayabilirsiniz.

[Düzenle not]: Bu variable variables olarak bilinen bir kavramdır, ve new komutu tanıtıldı kılavuzda bazı örnekler var.

Bu gibi durumlarda i fabrika yöntemleri kullanın. kolayca soyut sınıflar tanımlanabilir:

class Foobar {

    public function __construct($foo, $bar) 
    {
        // do something
    }

    static public function factory($foo, $bar) 
    {
        return new self($foo, $bar);
    }
}

Bu ile kullanabilirsiniz call_user_func_array():

$my_foobar_obj = call_user_func_array('Foobar::factory', array($foo, $bar));

Chris'in cevap @ dayanarak (http://stackoverflow.com/a/2550465/1806628), burada yansıma sınıfların bir kullanım şöyledir:

abstract class A{
    // the constructor writes out the given parameters
    public function __construct(){
        var_dump(func_get_args());
    }

    public function copy(){
        // find our current class' name, __CLASS__ would return A
        $thisClass = get_class($this);
        $tmp = new ReflectionClass($thisClass);
        // pass all the parameters recieved to the new object
        $copy = $tmp->newInstanceArgs(func_get_args());

        return $copy;
    }
}

class B extends A{}

// create a new B object, with no parameters
$b = new B();

// create another b, but with other parameters
$c = $b->copy('the parameter of the copied B');

Bir ata sınıfında bir nesne kopyalama işlevini yapmak ve çocuk sınıfları gelecekte parametreleri, gerek olup olmadığını bilmiyorum, isterseniz bu yararlıdır.

İşte ne istediğini temiz bir versiyonu:

class ClassName {
    public static function init(){       
        return (new ReflectionClass(get_called_class()))->newInstanceArgs(func_get_args());        
    }

    public static function initArray($array=[]){       
        return (new ReflectionClass(get_called_class()))->newInstanceArgs($array);        
    }

    public function __construct($arg1, $arg2, $arg3){
        ///construction code
    } 
}

Normal ugly method of creating a new object instance using new

$obj = new ClassName('arg1', 'arg2', 'arg3');
echo $obj->method1()->method2();

Static call using init instead of new

echo ClassName::init('arg1', 'arg2', 'arg3')->method1()->method2();

Static call using initArray instead of new

echo ClassName::initArray(['arg1', 'arg2', 'arg3'])->method1()->method2();