2012-10-12 42 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