2013-07-02 2 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 цикл вроде этого:

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 внутри функция (НЕ статическая), она работает нормально. Я не могу помещать его в конструктор, потому что этот класс используется статически, поэтому конструктор не будет вызван.

Мой вопрос: возможно ли это сделать в статическом массиве? Или я должен просто сделать что-то еще?

(Дополнительный вопрос: Есть ли лучший способ, чем это сделать достижение)

+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

Смежные вопросы