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.