การเรียกใช้เมธอดคลาสไดนามิกใน PHP


88

มีวิธีเรียกใช้เมธอดแบบไดนามิกในคลาสเดียวกันสำหรับ PHP หรือไม่? ฉันไม่มีไวยากรณ์ที่ถูกต้อง แต่ฉันต้องการทำสิ่งที่คล้ายกับสิ่งนี้:

$this->{$methodName}($arg1, $arg2, $arg3);

มันเป็นคำถามเดิมหรือไม่? ฉันกำลังมองหาการเรียกใช้วิธีการแบบไดนามิกและฉันพบคำถามนี้ มันเป็นไวยากรณ์เดียวกันที่กำหนดโดย andy.gurin และฉันไม่เห็นลิงก์ที่แสดงการอัปเดตของคำถาม อย่างไรก็ตาม ... ขอบคุณที่ถามและขอบคุณผู้ร่วมให้ข้อมูล :-)
Luc M

5
@Luc - มันเป็นคำถามเดิม ปรากฎว่าฉันมีไวยากรณ์ที่ถูกต้องเมื่อฉันถาม แต่มีบางอย่างผิดปกติกับรหัสของฉันจึงใช้งานไม่ได้
VirtuosiMedia

คำตอบ:


176

มีวิธีทำมากกว่าหนึ่งวิธี:

$this->{$methodName}($arg1, $arg2, $arg3);
$this->$methodName($arg1, $arg2, $arg3);
call_user_func_array(array($this, $methodName), array($arg1, $arg2, $arg3));

คุณยังสามารถใช้ API การสะท้อนhttp://php.net/manual/en/class.reflection.php


ฉันเดาว่าบางทีฉันมีไวยากรณ์ที่ถูกต้องดังนั้นมีอย่างอื่นผิดกับรหัสของฉันเนื่องจากมันทำงานไม่ถูกต้อง อืม ...
VirtuosiMedia

คำพูดสำหรับผู้เบื่อหน่ายหากวิธีการของคุณถูกเรียกใช้กับวัตถุและทดสอบด้วย PHPUnit call_user_func_arrayเป็นคำที่เหมาะสำหรับคุณ
ตกลงแน่

คุณเป็นเพื่อนของฉันช่วยวันของฉัน! ฉันโทรมาcall_user_func_array($this->$name, ...)และสงสัยว่าทำไมมันถึงใช้ไม่ได้!
Pubudu Dodangoda


10

คุณสามารถใช้ Overloading ใน PHP: Overloading

class Test {

    private $name;

    public function __call($name, $arguments) {
        echo 'Method Name:' . $name . ' Arguments:' . implode(',', $arguments);
        //do a get
        if (preg_match('/^get_(.+)/', $name, $matches)) {
            $var_name = $matches[1];
            return $this->$var_name ? $this->$var_name : $arguments[0];
        }
        //do a set
        if (preg_match('/^set_(.+)/', $name, $matches)) {
            $var_name = $matches[1];
            $this->$var_name = $arguments[0];
        }
    }
}

$obj = new Test();
$obj->set_name('Any String'); //Echo:Method Name: set_name Arguments:Any String
echo $obj->get_name();//Echo:Method Name: get_name Arguments:
                      //return: Any String


3

หากคุณกำลังทำงานในชั้นเรียนใน PHP ฉันขอแนะนำให้ใช้ฟังก์ชัน __call ที่มากเกินไปใน PHP5 คุณสามารถดูข้อมูลอ้างอิงได้ที่นี่ที่นี่

โดยทั่วไป __call ใช้สำหรับฟังก์ชันไดนามิกที่ __set และ __get ทำสำหรับตัวแปรใน OO PHP5


2

ยังคงใช้ได้ทุกปี! ตรวจสอบให้แน่ใจว่าคุณได้ตัด $ methodName หากเป็นเนื้อหาที่ผู้ใช้กำหนด ฉันไม่สามารถให้ $ this -> $ methodName ทำงานได้จนกว่าฉันจะสังเกตเห็นว่ามันมีช่องว่างชั้นนำ


หากเป็นเนื้อหาที่ผู้ใช้กำหนดเองให้แน่ใจว่าคุณทำมากกว่าแค่ตัดชื่อ! เช่น ... security check it! ;)
เอิร์ก

ที่ใดที่หนึ่งบนอินเทอร์เน็ตฉันอธิบายวิธีการแปลงผู้ใช้ที่ป้อน utf8 เป็นอักขระที่ปลอดภัยสำหรับ Windows QuickBooks พาฉันผ่านนักเขียนคนนั้น - และทำไม QB ไม่ได้เป็นส่วนหนึ่งของวิธีการขายอีกต่อไป ...
Chris K

คุณอนุญาตให้ไคลเอ็นต์ระบุอินพุตหรือไม่ซึ่งเรียกใช้วิธีการบางอย่างแบบไดนามิกหรือไม่! ฉันไม่มีคำพูด
Mcsky

ได้รับการตรวจสอบอย่างชัดเจนและตรวจสอบว่าคลาสนั้นมีเมธอดที่ตั้งชื่อดังกล่าวจริง มีหลายวิธีในการตรวจสอบค่า มันเต้นคำสั่งสวิตช์ที่ยาว
Snapey

1

ในกรณีของฉัน

$response = $client->{$this->requestFunc}($this->requestMsg);

ใช้ PHP SOAP


2
ฉันไม่แน่ใจ แต่โปรดระวังปัญหาด้านความปลอดภัย
tom10271

1

คุณสามารถจัดเก็บวิธีการในตัวแปรเดียวโดยใช้การปิด:

class test{        

    function echo_this($text){
        echo $text;
    }

    function get_method($method){
        $object = $this;
        return function() use($object, $method){
            $args = func_get_args();
            return call_user_func_array(array($object, $method), $args);           
        };
    }
}

$test = new test();
$echo = $test->get_method('echo_this');
$echo('Hello');  //Output is "Hello"

แก้ไข: ฉันได้แก้ไขโค้ดแล้วและตอนนี้เข้ากันได้กับ PHP 5.3 อีกตัวอย่างหนึ่งที่นี่

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