Yeni bir sınıf örneğini oluşturmak için bir call_user_func () eşdeğer var mı?

3 Cevap php

Nasıl kurucusuna gönderilecek argümanlar verilen bir dizi ile bir sınıf oluşturabiliriz? Çizgisinde bir şey:

class a {
    var $args = false;
    function a() {$this->args = func_get_args();}
}

$a = call_user_func_array('new a',array(1,2,3));
print_r($a->args);

İdeal olarak bu PHP4 ve PHP5 hem de, sınıfına değişiklik olmadan, çalışmak gerekiyor. Herhangi bir fikir?

3 Cevap

ReflectionClass:newInstance() (veya newInstanceArgs ()) bunu diyelim.

örneğin

class Foo {
  public function __construct() {  
    $p = func_get_args();
    echo 'Foo::__construct(', join(',', $p), ') invoked';
  }
}

$rc = new ReflectionClass('Foo');
$foo = $rc->newInstanceArgs( array(1,2,3,4,5) );

edit: ReflectionClass olmadan ve muhtemelen uyumlu php4 (üzgünüm, eldeki hiçbir php4 şu anda)

class Foo {
  public function __construct() {  
    $p = func_get_args();
    echo 'Foo::__construct(', join(',', $p), ') invoked';
  }
}

$class = 'Foo';
$rc = new $class(1,2,3,4);

speed comparison: Since the speed of reflection has been mentioned here's a little (synthetic) test

define('ITERATIONS', 100000);

class Foo {
  protected $something;
  public function __construct() {
    $p = func_get_args();
    $this->something = 'Foo::__construct('.join(',', $p).')';
  }
}

$rcStatic=new ReflectionClass('Foo'); 
$fns = array(
  'direct new'=>function() { $obj = new Foo(1,2,3,4); },
  'indirect new'=>function() { $class='Foo'; $obj = new $class(1,2,3,4); }, 
  'reflection'=>function() { $rc=new ReflectionClass('Foo'); $obj = $rc->newInstanceArgs( array(1,2,3,4) ); },
  'reflection cached'=>function() use ($rcStatic) { $obj = $rcStatic->newInstanceArgs( array(1,2,3,4) ); },
);


sleep(1);
foreach($fns as $name=>$f) {
  $start = microtime(true);
  for($i=0; $i<ITERATIONS; $i++) {
    $f();
  }
  $end = microtime(true);
  echo $name, ': ', $end-$start, "\n";
  sleep(1);
}

benim (çok hızlı değil) notebook yazdırır

direct new: 0.71329689025879
indirect new: 0.75944685935974
reflection: 1.3510940074921
reflection cached: 1.0181720256805

O kadar da kötü değil, değil mi?

Factory Method pattern bakmak ve kontrol this example

Vikipedi:

The factory method pattern is an object-oriented design pattern. Like other creational patterns, it deals with the problem of creating objects (products) without specifying the exact class of object that will be created.

Bunun için özel bir Fabrika kullanmak istemiyorsanız, acaba hala wrap Volker's code bir işlevi, örneğin

/**
 * Creates a new object instance
 *
 * This method creates a new object instance from from the passed $className
 * and $arguments. The second param $arguments is optional.
 *
 * @param  String $className class to instantiate
 * @param  Array  $arguments arguments required by $className's constructor
 * @return Mixed  instance of $className
 */
function createInstance($className, array $arguments = array())
{
    if(class_exists($className)) {
        return call_user_func_array(array(
            new ReflectionClass($className), 'newInstance'), 
            $arguments);
    }
    return false;
}

Eğer yaratacaktır PHP kodu bir dize değerlendirmek sağlar PHP fonksiyon eval() bir göz atın. Bu temiz değil. PHP 4 ve 5 iki çalışır ama hızlı.