Reputation: 3985
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?)
Upvotes: 2
Views: 1436
Reputation: 71384
It is not possible to do in a static array like this. The property declaration must be constant as noted in PHP docs here (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.
What you could perhaps do is have the function names defined statically, i.e.:
private static $rules = array(
'card'=>array('function1', 'function2'),
'set'=>array('function3', 'function4')
);
And then you could simply use these references to call NAMED method calls:
public static function function1 () {
// some logic
}
public static function function2 () {
// some logic
}
However, this whole thing seems very clunky. Seems to me you might want to have an achievement interface which defines certain methods (i.e. checkAchievements
) and then have concrete implementing classes for cards, sets, etc.
Upvotes: 1
Reputation: 7784
No way you can pre-declare them (anonymous functions) in a class. You can do it inside a class method though:
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
Upvotes: 4
Reputation: 23777
Current PHP grammar only supports primitive types, arrays and compile time constants in predefined class variables. For an exact list of what it supports see also http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_language_parser.y#945.
What you can do is maybe declaring your class' methods as private and the use __callStatic as a wrapper. If the static property is then not yet set, set them. And then call the class method.
Or just make some setup at the beginning. like @Jari suggested.
Upvotes: 1