2012-10-12 46 views
14

我想迭代一個數組並根據每個項目動態創建函數。我的僞代碼:動態創建PHP類函數

$array = array('one', 'two', 'three'); 

foreach ($array as $item) { 
    public function $item() { 
     return 'Test'.$item; 
    } 
} 

我該如何去做這件事?

+4

我可以問你爲什麼要建立這個功能 – Baba

+0

PHP不喜歡的工作。 – hakre

+0

添加太多動態會使程序無法讀取 - 這相當於無法維護。你可以詳細瞭解你有什麼和你想得到什麼? – Sven

回答

22

您可以使用魔術方法__call()來代替「創建」功能,以便在調用「不存在」功能時,可以處理它並執行正確的操作。

事情是這樣的:

class MyClass{ 
    private $array = array('one', 'two', 'three'); 

    function __call($func, $params){ 
     if(in_array($func, $this->array)){ 
      return 'Test'.$func; 
     } 
    } 
} 

然後,您可以撥打:

$a = new MyClass; 
$a->one(); // Testone 
$a->four(); // null 

DEMO:http://ideone.com/73mSh

編輯:如果您使用的是PHP 5.3+,你居然可以做你正在試圖做你的問題!

class MyClass{ 
    private $array = array('one', 'two', 'three'); 

    function __construct(){ 
     foreach ($this->array as $item) { 
      $this->$item = function() use($item){ 
       return 'Test'.$item; 
      }; 
     } 
    } 
} 

這並不工作,但你不能直接調用$a->one(),你需要save it as a variable

$a = new MyClass; 
$x = $a->one; 
$x() // Testone 

DEMO:http://codepad.viper-7.com/ayGsTu

+0

@NullUserException:感謝您添加'__call()'是一個「魔術方法」的事實。 –

+0

您也可以使用神奇的'__get()'函數調用閉包/回調函數:,請參閱[在PHP中動態創建實例方法](http://stackoverflow.com/questions/3231365/dynamically-create-instance- method-in-php) - 如果你真的認爲'__call()'或'__get()'是被請求的,請將現有的問題建議爲重複。 – hakre

+1

PHP如何對這個文件進行阻止,以便編輯器不會警告「不存在的函數」? – Kyslik

-2

不知道關於你的情況的使用情況,您可以使用create_function創建匿名函數。

+2

我不認爲'create_function'可以用來創建方法,我認爲避免它是明智的。由@RockedHazmat提出的魔術方法'__call'是更好的選擇。 – GolezTrol

2
class MethodTest 
{ 
    private $_methods = array(); 

    public function __call($name, $arguments) 
    { 
     if (array_key_exists($name, $this->_methods)) { 
      $this->_methods[$name]($arguments); 
     } 
     else 
     { 
      $this->_methods[$name] = $arguments[0]; 
     } 
    } 
} 

$obj = new MethodTest; 

$array = array('one', 'two', 'three'); 

foreach ($array as $item) 
{ 
    // Dynamic creation 
    $obj->$item((function ($a){ echo "Test: ".$a[0]."\n"; })); 
    // Calling 
    $obj->$item($item); 
} 

上面的例子將輸出:

Test: one 
Test: two 
Test: three 
+0

有沒有辦法繞過'$ a [0]'並且只需要'$ a'? – duck

+0

@duck class MethodTest { public function __call($ name,$ arguments) { echo「」 。 「方法:」。$ name。「\ n」 。 (!empty($ arguments)?「參數:」。implode(',',$ arguments):「無參數!」)。 「\ n」 個; } } $ obj = new MethodTest; $ obj-> ExecTest('par 1','par 2','others ...'); $ obj-> ExecTest(); – q81