สร้างอินสแตนซ์คลาส PHP ด้วยสตริง


223

ฉันมีสองชั้นclass ClassOne { }และclass ClassTwo {}. ฉันได้รับสตริงที่สามารถเป็นได้ทั้งหรือ"One""Two"

แทนที่จะใช้switchคำสั่งแบบยาวเช่น:

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

มีวิธีที่ฉันสามารถสร้างอินสแตนซ์โดยใช้สตริงเช่นnew Class("Class" . $str);?

คำตอบ:


484

ใช่คุณสามารถ!

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

เมื่อใช้เนมสเปซให้ระบุชื่อที่ผ่านการรับรองโดยสมบูรณ์ :

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

สิ่งดีๆอื่น ๆ ที่คุณสามารถทำได้ใน PHP คือ:
ตัวแปรตัวแปร :

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

และฟังก์ชั่นตัวแปรและวิธีการ

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

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

1
ขอบคุณสำหรับตัวอย่าง!
Joel

28
FYI คุณไม่สามารถใช้ตัวแปรบางส่วนได้ เช่น. $my_obj = Package\$class_name();. แต่คุณต้อง$class_name = "Package\\" . $class_name; $my_obj = new $class_name();
Birla

14
โปรดทราบว่าเมื่อใช้ namespaces คุณต้องระบุเส้นทางแบบเต็ม:$className = '\Foo\Bar\MyClass'; $instance = new $className();
Giel Berkers เมื่อ

5
ไม่มีช้อน ... เพียง php
Captain Hypertext

4
แต่คำถามหนึ่งข้อ วิธีการที่อธิบายไว้ข้างต้นสามารถใช้ในการสร้างคลาสอินสแตนซ์ใหม่ได้ ถ้าฉันต้องการเรียกเมธอดของคลาสที่มีอยู่แบบสแตติก? ฉันพยายามดังนี้$model = $user_model::find()->All(); ที่$user_modelเป็นตัวแปรที่มีสตริงของชั้นถูกเรียกว่า
ราเมษ Pareek

22

คุณสามารถใช้ไวยากรณ์ต่อไปนี้เพื่อสร้างคลาสใหม่ (ซึ่งเป็นประโยชน์ถ้าคุณกำลังสร้างโรงงาน ):

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

ในฐานะที่เป็น (ตัวอย่างล้ำ) วิธีการโรงงานตัวอย่าง:

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
คุณไม่พลาดจุดระหว่างชื่อคลาสและส่วนขยายหรือไม่ require_once($className.'php'); ->require_once($className.'.php');
J Quest


4

ให้บอกว่าClassOneถูกกำหนดเป็น:

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

}

ใช้ PHP รีเฟลคชั่น

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

สร้างอินสแตนซ์ใหม่:

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

เรียกวิธีการ:

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

ใช้ตัวแปรเป็นวิธีการ:

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

//prints "Banana"

การใช้รีเฟลคชั่นแทนการใช้สตริงดิบเพื่อสร้างออบเจ็กต์ช่วยให้คุณควบคุมออบเจ็กต์ของคุณได้ดีขึ้นและทดสอบได้ง่ายขึ้น (PHPUnit ต้องอาศัยรีเฟลคชันมาก)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.