2010-04-14 23 views
12

Tôi có một hàm lấy đối số variadic, mà tôi nhận được từ func_get_args().Gọi một hàm tạo từ các đối số biến với PHP

Chức năng này cần gọi hàm tạo bằng các đối số đó. Tuy nhiên, tôi không biết làm thế nào để làm điều đó.

Với call_user_func, bạn có thể gọi hàm với một loạt các đối số, nhưng làm cách nào bạn gọi một hàm tạo từ nó? Tôi không thể truyền mảng đối số cho nó; nó phải tin rằng tôi đã gọi nó là "bình thường".

Cảm ơn bạn!

+0

Vì PHP 5.6 bạn có thể sử dụng _argument unpacking_: 'new SomeClass (... ['arg1', 'arg2']); ' – David

Trả lời

20

Đối với PHP < 5.3 không dễ dàng thực hiện được mà không cần tạo một phiên bản của lớp với call_user_func_array. Tuy nhiên với Reflection này là khá tầm thường:

$reflection = new ReflectionClass('yourClassName'); 
$instance = $reflection->newInstanceArgs($yourArrayOfConstructorArguments); 
+0

Một tính năng khác của PHP 5.3 mà tôi không biết. Cảm ơn, nó sẽ làm điều đó. – zneak

+1

Cảm ơn bạn về ví dụ. Đây có lẽ là điều đầu tiên trong hướng dẫn sử dụng PHP mà tôi đã tìm thấy không được giải thích rất rõ. –

+5

@zneak, 'ReflectionClass :: newInstanceArgs' không phải là mới trong PHP 5.3, chúng tôi đã có nó khoảng từ năm 2006 khi nó được phát hành với PHP 5.1.3. @byronh, có điều gì đặc biệt mà bạn tìm thấy không được giải thích hay bạn đang đề cập đến các phần được gắn nhãn là "không có giấy tờ"? (Hãy gửi email cho tôi, [email protected]) – salathe

-2

Nếu vì một số lý do bạn không thể sử dụng ReflectionClass::newInstanceArgs đây là một giải pháp sử dụng eval():

function make_instance($class, $args) { 
    $arglist = array(); 
    $i = 0; 
    foreach($args => &$v) { 
     $arglist[] = $n = '_arg_'.$i++; 
     $$n = &$v; 
    } 
    $arglist = '$'.implode(',$',$arglist); 
    eval("\$obj = new $class($arglist);"); 
    return $obj; 
} 
$instance = make_instance('yourClassName', $yourArrayOfConstructorArguments); 

Lưu ý rằng việc sử dụng chức năng này cho phép bạn để vượt qua đối số bằng cách tham chiếu đến hàm tạo, không được chấp nhận với ReflectionClass::newInstanceArgs.

+0

Có gì sai với câu trả lời này? Có ý kiến ​​gì không? Có phải chỉ vì 'eval'? Tôi đã tuyên bố rõ ràng ngay từ đầu, đây là giải pháp thay thế sử dụng 'eval' – DUzun

Các vấn đề liên quan