una que otro llamar instancia funciones funcion ejemplos desde clases clase archivo php class php4

otro - que es una instancia en php



¿Existe un call_user_func() equivalente para crear una nueva instancia de clase? (2)

¿Cómo puedo crear una clase con una matriz dada de argumentos para enviar al constructor? Algo como:

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);

Lo ideal es que esto funcione, sin modificaciones en la clase, tanto en PHP4 como en PHP5. ¿Algunas ideas?


Echa un vistazo al patrón Método de fábrica y echa un vistazo a este ejemplo

De la Wikipedia:

El patrón de método de fábrica es un patrón de diseño orientado a objetos. Al igual que otros patrones creacionales, se ocupa del problema de crear objetos (productos) sin especificar la clase exacta de objeto que se creará.

Si no quiere usar una fábrica dedicada para esto, aún puede ajustar el código de Volker en una función, por ejemplo:

/** * 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; }


ReflectionClass:newInstance() (o newInstanceArgs ()) vamos a hacer eso.

p.ej

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) );

editar: sin ReflectionClass y probablemente compatible con php4 (lo siento, no php4 a la mano en este momento)

class Foo { public function __construct() { $p = func_get_args(); echo ''Foo::__construct('', join('','', $p), '') invoked''; } } $class = ''Foo''; $rc = new $class(1,2,3,4);

comparación de velocidad: como se mencionó la velocidad de reflexión, aquí hay una pequeña prueba (sintética)

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); }

que imprime en mi cuaderno (no tan rápido)

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

¿No es malo, verdad?