2013-07-02 53 views
2

我試圖爲記憶網站製作一個成就係統(「你記憶50張卡片」等),而我嘗試使用的方法是匿名數組功能:PHP - 作爲靜態數組元素的匿名函數

class AchievementController extends Controller 
{ 
    private static $rules = array(
     'card'=>array(
      1=>function() { 
       //do check for achievement 
      }, 
      2=>function() { 
       //do check for achievement 
      } 
     ), 
     'set'=>array(
      5=>function() { 
       //do check for achievement 
      }, 
      6=>function() { 
       //do check for achievement 
      }, 
     ) 
    ); 
    //... 
} 

的想法是,爲成就某些類型的規則將在特定的時間,也就是當你學習新卡檢查時,card子集將被檢查。我曾希望使用foreach循環是這樣的:如果我宣佈$rules

PHP Parse error: syntax error, unexpected 'function' (T_FUNCTION) in /.../controllers/achievement.php on line 24

foreach(self::$rules[$type] as $rule) 
{ 
    $rule(); 
} 

然而,當我嘗試申報$rules陣列,我得到這個錯誤一個函數(不是靜態的),它工作得很好。我不能把它放在構造函數中,因爲這個類是靜態使用的,所以不會調用構造函數。

我的問題是,我有可能在靜態數組中做到這一點?或者我應該只是去做別的事情?

(額外的問題:是否有比這更好的方式來做到的成就)

+0

你運行的是什麼版本的PHP ...匿名函數直到5.3纔可用。 – Orangepill

+1

爲什麼這麼多關閉?似乎不太可能所有的邏輯是互斥的?因此,考慮子類化和使用多態性。 –

+0

@Orangepill,我使用的是5.3版本。 – musicnothing

回答

4

沒辦法,你可以預先聲明它們(匿名函數)類。你可以做一個類的方法,雖然裏面:

class AchievementController extends Controller { 
    public static $rules = array() ; 

    public static function setup(){ 
    self::$rules = array(
     0 => function(){ 
     echo "One-statement array" ; 
     }) ; 

    //OR 


    self::$rules[0] = function(){ 
     //Echo "ASD" ; 
    } ; 
    self::$rules[1] = function(){ 
     //Echo "ASD2" ; 
    } 
    } 
} 

AchievementController::setup() ; //Just calling pseudo-constructor for static class 
+0

實現了這一點,它的工作很好。 – musicnothing

+0

很高興能聽到:) – vikingmaster

1

這是不可能在一個靜態數組這樣做。財產聲明必須是不變的,如PHP文檔(http://www.php.net/manual/en/language.oop5.properties.php)中所述。

This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.

你也許可以做的是有函數名靜態定義,即:

private static $rules = array(
    'card'=>array('function1', 'function2'), 
    'set'=>array('function3', 'function4') 
); 

然後你可以簡單地使用這些引用調用一個名爲方法調用:

public static function function1() { 
    // some logic 
} 

public static function function2() { 
    // some logic 
} 

但是,這整個事情似乎非常笨重。在我看來,你可能想要有一個成就界面,它定義了某些方法(例如checkAchievements),然後具體實現卡片,集合等類。

+0

沒有使用的閉包()不需要運行時信息。 – bwoebi

+1

@bwoebi在編譯時無法評估閉包。這不是一個恆定的價值。如果閉包確實做了一些小事,比如'function(){return true; }'這是不變的,比根本就不需要關閉。 –

+0

恩,我們稱之爲靜態依賴注入。在類 – bwoebi

1

當前PHP語法只支持基本類型,數組和編譯預定義類變量的時間常數。有關它支持的確切列表,另請參閱http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_language_parser.y#945

你可以做的是可能聲明你的類的方法是私有的,並且使用__callStatic作爲包裝。如果靜態屬性尚未設置,請設置它們。然後調用類方法。

或者只是在開始時進行一些設置。就像@Jari所建議的那樣。

+0

謝謝。這很清楚。 – musicnothing