Membuat instance kelas PHP dengan string

223

Saya punya dua kelas, class ClassOne { }dan class ClassTwo {}. Saya mendapatkan string yang bisa berupa "One"atau "Two".

Alih-alih menggunakan switchpernyataan panjang seperti:

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

Apakah ada cara saya bisa membuat contoh menggunakan string, yaitu new Class("Class" . $str);?

Joel
sumber

Jawaban:

484

Ya kamu bisa!

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

Saat menggunakan ruang nama, berikan nama yang memenuhi syarat :

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

Hal keren lainnya yang dapat Anda lakukan di php adalah:
Variabel variabel :

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

Dan fungsi & metode variabel.

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

$method = 'doStuff';
$object = new MyClass();
$object->$method(); // calls the MyClass->doStuff() method. 
Bob Fanger
sumber
1
Terima kasih atas contohnya!
Joel
28
FYI, Anda tidak dapat menggunakan sebagian variabel. misalnya. $my_obj = Package\$class_name();. Sebaliknya, Anda harus$class_name = "Package\\" . $class_name; $my_obj = new $class_name();
Birla
14
Harap perhatikan saat menggunakan ruang nama, Anda harus menyediakan jalur lengkap:$className = '\Foo\Bar\MyClass'; $instance = new $className();
Giel Berkers
5
Tidak ada sendok ... hanya php.
Kapten Hypertext
4
tapi satu pertanyaan. Metode yang dijelaskan di atas dapat digunakan untuk membuat instance kelas baru. Bagaimana jika saya ingin memanggil metode kelas yang ada secara statis? Saya mencoba sebagai berikut: di $model = $user_model::find()->All(); mana $user_modelvariabel berisi string dari kelas yang dipanggil
Ramesh Pareek
22

Anda cukup menggunakan sintaks berikut untuk membuat kelas baru (ini berguna jika Anda membuat pabrik ):

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

Sebagai metode pabrik contoh (sangat kasar):

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.');
}
John Parker
sumber
1
Apakah Anda tidak kehilangan titik di antara nama kelas dan ekstensi? require_once($className.'php'); ->require_once($className.'.php');
J Quest
4

Katakanlah ClassOnedidefinisikan sebagai:

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

}

Menggunakan Refleksi PHP;

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

Buat Mesin Virtual baru:

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

Panggil metode:

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

Gunakan variabel sebagai metode:

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

//prints "Banana"

Menggunakan Refleksi alih-alih hanya menggunakan string mentah untuk membuat objek memberi Anda kontrol yang lebih baik atas objek Anda dan lebih mudah diuji (PHPUnit sangat bergantung pada Refleksi)

Dibuat kembali
sumber