PHP - 匿名函数作为静态数组元素

时间:2013-07-02 21:32:07

标签: php class function static anonymous-function

我正在尝试为记忆网站创建一个成就系统(“你记住了50张卡片”等),我试图使用的方法是一组匿名函数:

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循环:

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

但是,当我尝试声明$rules数组时,我收到此错误:

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

如果我在函数内声明$rules(非静态),它就可以了。我不能把它放在构造函数中,因为这个类是静态使用的,所以不会调用构造函数。

我的问题是,我可以在静态数组中执行此操作吗?或者我应该做别的事情?

(额外的问题:有没有比这更好的方法来取得成就?)

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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),然后为卡片,集合等设置具体的实现类。

答案 2 :(得分:1)

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

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

或者只是在开头做一些设置。像@Jari建议的那样。