2010-10-30 46 views
5

Tôi đang chuyển tất cả các cuộc gọi đến chức năng ánh xạ chính và sau đó nó sẽ tự động gọi hàm khác dựa trên chuỗi (cho đến khi phần này, mọi thứ trở nên dễ dàng) vấn đề là tôi muốn chuyển đối số với hàm thứ hai và các tham số này có thể khác nhau. Sau đây là nhất định (không nên thay đổi):đối số chức năng động

function test1($x){ 
    echo $x; 
} 

function test2($x, $y){ 
    echo $x * $y; 
} 

và bây giờ đến chức năng lập bản đồ

function mapping ($str){ 
     switch ($str){ 
      case 'name1': 
       $fn_name = 'test1'; 
       $var = 5; 
       break; 
      case 'name2': 
       $fn_name = 'test2'; 
       $var = 5; 
       break; 
     } 
     $this->{$fn_name}($var); 
} 

Và sau đó điều này sẽ chạy các bản đồ:

$this->mapping('name1'); 
$this->mapping('name2'); // This one will crash as it need two variables 

Tất nhiên ở trên được đơn giản hóa để tập trung vào vấn đề không phải là mục đích của mã. Vấn đề là khi hàm có nhiều hơn một đối số (có thể dễ dàng xảy ra). Tôi hy vọng có trường hợp chuyển đổi và dựa trên cách các thông số trường hợp được điền, dòng $this->{$fn_name}($var); sẽ hoạt động.

Bạn có thể vui lòng tư vấn hoặc cho tôi ý tưởng hay không, biết rằng không thể thay đổi cấu trúc hàm (test1, test2). Tôi có thể không đột nhiên bắt đầu sử dụng func_get_args() hoặc func_get_arg()

Trả lời

5

Bạn có thể sử dụng ReflectionFunction và phương pháp invokeArgs() của nó để vượt qua các biến trong một mảng:

function mapping ($str) { 
    switch ($str) { 
     case 'name1': 
      $fn_name = 'test1'; 
      $fn_args = array(5); 
      break; 
     case 'name2': 
      $fn_name = 'test2'; 
      $fn_args = array(5, 10); 
      break; 
    } 

    $function = new ReflectionFunction($fn_name); 
    $function->invokeArgs($fn_args); 
} 
+1

Đề xuất của bạn tuyệt vời mệt mỏi và hoạt động tốt. nhưng sau khi khám phá trong php.net nếu tìm thấy call_user_func_array() và nó giải quyết vấn đề của tôi một cách hoàn hảo nhưng tôi vẫn nợ tất cả cho bạn :) – bhefny

+2

FYI - ReflectionFunction sẽ không hoạt động trên các phương thức lớp - ví dụ hoặc tĩnh – phirschybar

2

Kể từ mapping() trong mã của bạn có vẻ là một phương pháp học, thay thế nó với:

public function __call($method, $args) 
{ 
    // possibly validate $method first, e.g. with a static map 
    return call_user_func_array($method, $args); 
} 

Ví dụ:

function foo($foo) { echo $foo; } 
function bar($foo, $bar) { echo "$foo - $bar"; } 

$this->foo('foo'); // outputs 'foo' 
$this->bar('foo', 'bar'); // outputs 'foo - bar' 

Điều này có nghĩa là lớp học của bạn không nên có các phương thức foo() hoặc bar() cho số __call() để được gọi.

Dường như là một vấn đề khá phức tạp. Có lẽ một giải pháp thanh lịch hơn cho những gì bạn đang cố gắng đạt được? :)

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