2

I'm attempting to make an achievement system for a memorization website ("You memorized 50 cards," etc.), and the method I'm trying to use is an array of anonymous functions:

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
            },
         )
    );
    //...
}

The idea is that certain types of rules for achievements will be checked at certain times, i.e. when you learn a new card, the card subset will be checked. I had hoped to use a foreach loop like this:

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

However, when I try to declare the $rules array, I get this error:

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

If I declare $rules inside a function (NOT static), it works just fine. I can't put it inside a constructor, because this class is being used statically, so no constructor will be called.

My question is, is it possible for me to do this in a static array? Or ought I just to do something else?

(Extra question: Is there a better way than this to do achievements?)

4

3 回答 3

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
于 2013-07-02T21:37:22.813 回答
1

在这样的静态数组中是不可能的。属性声明必须保持不变,如 PHP 文档中所述(http://www.php.net/manual/en/language.oop5.properties.php)。

这个声明可能包括一个初始化,但是这个初始化必须是一个常量值——也就是说,它必须能够在编译时被评估,并且不能依赖于运行时信息才能被评估。

您也许可以做的是静态定义函数名称,即:

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

然后您可以简单地使用这些引用来调用 NAMED 方法调用:

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

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

然而,这整件事看起来很笨拙。在我看来,您可能想要一个定义某些方法(即checkAchievements)的成就接口,然后为卡片、套装等提供具体的实现类。

于 2013-07-02T21:36:22.220 回答
1

当前的 PHP 语法仅支持预定义类变量中的原始类型、数组和编译时常量。有关它支持的确切列表,另请参见http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_language_parser.y#945

您可以做的可能是将您的类的方法声明为私有并使用 __callStatic 作为包装器。如果静态属性尚未设置,请设置它们。然后调用类方法。

或者只是在开始时进行一些设置。就像@Jari 建议的那样。

于 2013-07-02T21:37:49.510 回答