2010-01-21 33 views
51

請有經驗的PHP人士可以提供以下幫助。某處在我的代碼,我有一個非實例化類中的公共靜態方法的調用:PHP中的動態靜態方法調用?

$result = myClassName::myFunctionName(); 

不過,我想有很多這樣的課程,並根據在飛行中確定正確的類名用戶的語言。換句話說,我有:

$language = 'EN'; 

...我需要做一些事情,如:

$result = myClassName_EN::myFunctionName(); 

我知道我可以通過語言作爲參數的功能和內部處理它只是一個普通的類,但由於各種原因,我寧願有一個不同的解決方案。

這是否有任何意義,任何人?謝謝。

+1

要回答最後3行,除非你有一個特定的原因,你爲什麼不能實現「pass language as parameter」方式 – 2010-01-21 11:51:25

+3

是的,我有一個特定的原因......有關以更理智的方式管理翻譯,以處理這些類中發生的各種事情。這很複雜:) – Tom 2010-01-21 12:05:41

回答

96

使用call_user_func功能:

http://php.net/manual/en/function.call-user-func.php

實施例:

call_user_func('myClassName_' . $language . '::myFunctionName'); 
+24

結合'is_callable'和'method_exists',這也是我的建議。通過params看看'call_user_func_array' http://php.net/is_callable http://php.net/method_exists http://php.net/call_user_func_array – 2010-01-21 11:38:54

+1

+1,我同意nikc :-) – 2010-01-21 11:41:13

+0

這類作品似乎是最乾淨的解決方案。謝謝 – Tom 2010-01-21 11:49:32

3

雖然我覺得你處理的方式是一個非常糟糕的主意,我想我可能有一個解決方案

$className = 'myClassName_'.$language; 
$result = $className::myFunctionName(); 

我認爲這是你想要的

+0

哈哈!你打我45秒 – 2010-01-21 11:32:54

+0

請你能告訴我爲什麼這是一個壞主意? – Tom 2010-01-21 11:33:08

+0

您可以使用語言作爲參數,而是選擇爲其定義新的類。假設你想支持200種不同的語言,你會坐下來寫200個不同的課程。另外它會讓你的代碼難以閱讀和理解。 – marvin 2010-01-21 11:40:23

12

認爲你可以這樣做:

$classname = 'myClassName_' . $language; 
$result = $classname::myFunctionName(); 

這就是所謂的Variable Functions

+4

這太糟糕了,這隻適用於> = 5.3.0: – 2010-10-24 01:01:56

+0

對我來說,這是最好的解決方案,根據我的實驗臺,這也是最快的:100.000次迭代使用0.28s直接調用,0.32使用此解決方案,0.47使用call_user_func – fred727 2015-12-11 14:55:09

1

至於我能理解你的問題,你需要得到可使用get_class函數來完成的類名。另一方面,Reflection class可以幫助你在這裏,這是很好的,當談到方法,參數等OOP方式。

13

我會封裝在工廠中創建所需的類。

這樣,當您需要更改基本名稱或將語言映射到正確的類別的規則時,您將擁有一個入口點。

class YourClassFactory { 

     private $_language; 
     private $_basename = 'yourclass'; 

     public YourClassFactory($language) { 
      $this->_language = $language; 
     } 

     public function getYourClass() { 
      return $this->_basename . '_' . $this->_language; 
     }  
    } 

,然後,當你使用它:

$yourClass = $yourClassFactoryInstance->getYourClass(); 
$yourClass::myFunctionName(); 
0

解決方案,如:

$yourClass::myFunctionName(); 

將無法​​正常工作。 PHP會產生解析錯誤。

不幸的是,唯一的辦法是使用非常慢call_user_func()

+3

只有在<5.3.0中是不允許的。 5.3.0允許。 – 2010-10-24 01:03:55

+0

http://uk3.php.net/manual/en/language.variables.variable.php和http://uk3.php.net/manual/en/functions.variable-functions。 PHP :) – tftd 2011-05-07 22:40:13

6

正如temuri說,產生解析錯誤,試圖 '的$ className :: functionName' 時:

Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM ...

在我的情況下(靜態方法以2個參數),最佳的解決方案是使用call_user_func_array 2個陣列(由nikc.org的建議):

$result = call_user_func_array(array($className, $methodName), array($ard1, $arg2)); 

BR

-1

我知道這是一個古老的線程,但由於PHP 5.3.0,你應該使用forward_static_call

$result = forward_static_call(array('myClassName_EN', 'myFunctionName')); 

使用您的$語言變量,它可能看起來像:

$result = forward_static_call(array('myClassName_' . $language, 'myFunctionName')); 
+0

將無法​​正常工作。使用以下參數調用由函數參數給出的用戶定義的函數或方法。這個函數必須在方法上下文中調用,它不能在類之外使用......正如http://php.net/manual/en/function.forward-static-call.php中提到的那樣 – 2014-12-15 16:21:54

1

您可以輕鬆地做下一個:

<?php 

class B { 

    public static $t = 5; 

    public static function t($h) { 
     return "Works!" . $h; 
    } 
} 

$g = 't'; 
$class = 'B'; 

echo $class::$g('yes'); //Works! Yes 

,它會正常工作,在PHP 5.2測試> =