Crear instancia de clase PHP con una cadena


223

Tengo dos clases class ClassOne { } y class ClassTwo {}. Estoy obteniendo una cadena que puede ser "One"o "Two".

En lugar de usar un largo switch declaración como:

switch ($str) {
    case "One":
        return new ClassOne();
    case "Two":
        return new ClassTwo();
}

¿Hay alguna manera de crear una instancia con una cadena, es decir? new Class("Class" . $str); ?

Respuestas:


484

¡Sí tu puedes!

$str = 'One';
$class = 'Class'.$str;
$object = new $class();

Cuando use espacios de nombres, proporcione el nombre completo :

$class = '\Foo\Bar\MyClass'; 
$instance = new $class();

Otras cosas interesantes que puedes hacer en php son:
Variables variables :

$personCount = 123;
$varname = 'personCount';
echo $$varname; // echo's 123

Y funciones y métodos variables.

$func = 'my_function';
$func('param1'); // calls my_function('param1');

$method = 'doStuff';
$object = new MyClass();
$object->$method(); // calls the MyClass->doStuff() method. 

1
Gracias por los ejemplos!
Joel

28
Para su información, no puede usar parcialmente una variable. p.ej. $my_obj = Package\$class_name();. En cambio, tienes que$class_name = "Package\\" . $class_name; $my_obj = new $class_name();
Birla

14
Tenga en cuenta que cuando utilice espacios de nombres, debe proporcionar la ruta completa:$className = '\Foo\Bar\MyClass'; $instance = new $className();
Giel Berkers

55
No hay cuchara ... solo php.
Capitán Hipertexto

44
Pero una pregunta. El método descrito anteriormente se puede usar para crear una nueva instancia de clase. ¿Qué sucede si quiero llamar estáticamente a un método de una clase existente? Intenté lo siguiente: ¿ $model = $user_model::find()->All(); dónde se $user_modelllama la variable que contiene la cadena de la clase
Ramesh Pareek

22

Simplemente puede usar la siguiente sintaxis para crear una nueva clase (esto es útil si está creando una fábrica ):

$className = $whatever;
$object = new $className;

Como un método de fábrica de ejemplo (excepcionalmente crudo):

public function &factory($className) {

    require_once($className . '.php');
    if(class_exists($className)) return new $className;

    die('Cannot create new "' . $className . '" class - includes not found or class unavailable.');
}

1
¿No te pierdes un punto entre el nombre de la clase y la extensión? require_once($className.'php'); ->require_once($className.'.php');
J Quest


4

Digamos que ClassOnese define como:

public class ClassOne
{
    protected $arg1;
    protected $arg2;

    //Contructor
    public function __construct($arg1, $arg2)
    {
        $this->arg1 = $arg1;
        $this->arg2 = $arg2;
    }

    public function echoArgOne
    {
        echo $this->arg1;
    }

}

Usando PHP Reflection;

$str = "One";
$className = "Class".$str;
$class = new \ReflectionClass($className);

Crear una nueva instancia:

$instance = $class->newInstanceArgs(["Banana", "Apple")]);

Llamar a un método:

$instance->echoArgOne();
//prints "Banana"

Use una variable como método:

$method = "echoArgOne";
$instance->$method();

//prints "Banana"

El uso de Reflection en lugar de solo usar la cadena sin formato para crear un objeto le brinda un mejor control sobre su objeto y una capacidad de prueba más fácil (PHPUnit depende en gran medida de Reflection)

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.