Lời gọi phương thức lớp động trong PHP


88

Có cách nào để gọi động một phương thức trong cùng một lớp cho PHP không? Tôi không có đúng cú pháp, nhưng tôi đang tìm cách làm điều gì đó tương tự như sau:

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

Nó có phải là câu hỏi ban đầu? Tôi đang tìm kiếm một phương pháp động và tôi đã tìm thấy câu hỏi này. Nó <s cùng một cú pháp được đưa ra bởi andy.gurin và tôi không thấy liên kết hiển thị cập nhật về câu hỏi. Dù sao ... Nhờ đã hỏi và nhờ vào sự đóng góp cho :-)
Luc M

5
@Luc - Đó là câu hỏi ban đầu. Hóa ra là tôi đã đúng cú pháp khi tôi hỏi, nhưng có điều gì đó khác với mã của tôi, vì vậy nó không hoạt động.
VirtuosiMedia

Câu trả lời:


176

Có nhiều cách để làm điều đó:

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

Bạn thậm chí có thể sử dụng api phản chiếu http://php.net/manual/en/class.reflection.php


Tôi đoán có thể tôi đã viết đúng cú pháp, vì vậy có điều gì đó khác với mã của tôi vì nó không hoạt động chính xác. Hmm ...
VirtuosiMedia 30/10/08

Một lời khuyên đối với người mệt mỏi, nếu các phương thức của bạn đang được gọi trên các đối tượng và được thử nghiệm với PHPUnit, thì đây call_user_func_arraylà phương pháp dành cho bạn.
OK, chắc chắn

Bạn là bạn của tôi, vừa cứu được ngày của tôi! Tôi đã gọi call_user_func_array($this->$name, ...)và tự hỏi tại sao nó không hoạt động!
Pubudu Dodangoda

11

Chỉ cần bỏ qua các dấu ngoặc nhọn:

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

10

Bạn có thể sử dụng Overloading trong 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

Nếu bạn đang làm việc trong một lớp học bằng PHP, thì tôi khuyên bạn nên sử dụng hàm __call bị quá tải trong PHP5. Bạn có thể tìm tài liệu tham khảo tại đây .

Về cơ bản __call thực hiện cho các hàm động những gì __set và __get làm cho các biến trong OO PHP5.


2

Vẫn còn giá trị sau ngần ấy năm! Đảm bảo bạn cắt $ methodName nếu đó là nội dung do người dùng xác định. Tôi không thể làm cho $ this -> $ methodName hoạt động cho đến khi tôi nhận thấy nó có khoảng trắng ở đầu.


Nếu đó là nội dung do người dùng xác định, hãy đảm bảo bạn làm được nhiều việc hơn là chỉ cắt bớt tên! Chẳng hạn như ... kiểm tra an ninh nó! ;)
Erk

Ở một nơi nào đó trên internet, tôi đã trình bày chi tiết cách chuyển đổi người dùng đã nhập utf8 thành các ký tự an toàn cho windows. QuickBooks chạy tôi qua máy quay ép đó - và tại sao QB không còn là một phần của thế nào tôi hoàn thành bán hàng ...
Chris K

Bạn có thực sự cho phép khách hàng chỉ định một đầu vào, gọi động một số phương thức không ?! Tôi không có lời nào
Mcsky

Rõ ràng đã xác thực và kiểm tra xem lớp có thực sự chứa một phương thức được đặt tên như vậy không. Có nhiều cách để kiểm tra giá trị. Nó đánh bại một câu lệnh chuyển đổi dài dòng.
Snapey

1

Trong trường hợp của tôi.

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

Sử dụng PHP SOAP.


2
Tôi không chắc chắn nhưng phải cẩn thận về vấn đề an ninh
tom10271

1

Bạn có thể lưu trữ một phương thức trong một biến duy nhất bằng cách sử dụng một bao đóng:

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"

CHỈNH SỬA: Tôi đã chỉnh sửa mã và bây giờ nó tương thích với PHP 5.3. Một ví dụ khác ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.