你提到的這兩種方法都是好的,但有一定的侷限性:
使用正規表示法:
$request = 'blog';
$action = 'view';
$class = new $request(); // Creates an blog object
$class->$action(); // Runs the blog function view
使用用於實例化類的符號要求您事先知道每個類/方法接受的參數。所以你不能設計一個可以接受任意參數的factory pattern。
使用call_user_func_array()允許您使用任意參數。
$request = 'blog';
$action = 'view';
$params = array(
$_GET['category'],
$_GET['limit']
);
call_user_func_array(array($request, $action), $params);
所以上面的代碼等同於字面:
blog::view($_GET['category'], $_GET['limit']);
基本上,call_user_func_array()變平數組$參數,可以在它傳遞的每個值作爲參數傳遞給該方法博客::視圖( )。
爲了做同樣的動態/對象方法調用:
call_user_func_array(array(new $request, $action), $params);
然而,這並不與創建的任意類的一個實例,並將其傳遞的參數的任意數量的解決問題。要做到這一點,你可以使用ReflectionClass。
實施例:
$request = 'blog';
$action = 'view';
$configs = array('something', 'something else');
$params = array(
$_GET['category'],
$_GET['limit']
);
$instance = call_user_func_array(
array(new ReflectionClass($request), 'newInstance'),
$configs
);
$return = call_user_func_array(array($instance, $action), $params);
這將等效於:
$configs = array('something', 'something else');
$params = array(
$_GET['category'],
$_GET['limit']
);
$blog = new blog($configs[0], $configs[1]);
$blog->view($_GET['category'], $_GET['limit']);
有了這些工具可以動態實例化任意對象和傳遞的參數的任意數量的其__constructor()以及任何方法。
如果您的功能最好,請使用call_user_func_array()和ReflectionClass()。 如果您在性能方面表現最好,請不要擔心。良好的設計和功能可以提高性能。
您可能會閱讀KISS原則(http://en.wikipedia.org/wiki/KISS_principle)。使用Zend,CakePHP,CodeIgniter,Symphony等 – inakiabt 2009-09-04 20:15:37
我明白KISS,但即使Zend,CakePHP,CodeIgniter等也面臨同樣的問題。他們剛剛解決並從用戶那裏提取。 – 2009-09-04 21:23:25