Creazione dell'istanza della classe PHP con una stringa


223

Ho due lezioni class ClassOne { }e class ClassTwo {}. Ricevo una stringa che può essere "One"o "Two".

Invece di usare una switchdichiarazione lunga come:

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

C'è un modo in cui posso creare un'istanza usando una stringa, cioè new Class("Class" . $str);?

Risposte:


484

Si, puoi!

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

Quando si utilizzano gli spazi dei nomi, fornire il nome completo :

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

Altre cose interessanti che puoi fare in php sono:
Variabili variabili :

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

E funzioni e metodi variabili.

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

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

1
Grazie per gli esempi!
Gioele

28
Cordiali saluti, non è possibile utilizzare parzialmente una variabile. per esempio. $my_obj = Package\$class_name();. Invece devi$class_name = "Package\\" . $class_name; $my_obj = new $class_name();
Birla, il

14
Quando si utilizzano gli spazi dei nomi, è necessario fornire il percorso completo:$className = '\Foo\Bar\MyClass'; $instance = new $className();
Giel Berkers,

5
Non c'è un cucchiaio ... solo php.
Capitano Hypertext,

4
ma una domanda. Il metodo sopra descritto può essere utilizzato per creare una nuova istanza di classe. Cosa succede se desidero chiamare staticamente un metodo di una classe esistente? Ho provato come segue: $model = $user_model::find()->All(); dov'è $user_modella variabile che contiene la stringa della classe chiamata
Ramesh Pareek,

22

Puoi semplicemente usare la seguente sintassi per creare una nuova classe (questo è utile se stai creando una factory ):

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

Come metodo di fabbrica di esempio (eccezionalmente grezzo):

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
Non ti manca un punto tra il nome della classe e l'estensione? require_once($className.'php'); ->require_once($className.'.php');
J Quest,


4

Diciamo che ClassOneè definito come:

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

}

Utilizzo di PHP Reflection;

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

Crea una nuova istanza:

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

Chiama un metodo:

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

Utilizzare una variabile come metodo:

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

//prints "Banana"

L'uso di Reflection invece di utilizzare semplicemente la stringa non elaborata per creare un oggetto offre un migliore controllo sull'oggetto e una più facile testabilità (PHPUnit si basa fortemente su Reflection)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.