是否可以在类范围中定义匿名函数?

时间:2012-02-08 01:50:47

标签: php arrays class anonymous-function

我想在类中的PHP中为数组分配匿名函数,但我一直在语法错误上磕磕绊。

class Stuff {
  private $_preference_defaults = array(
    'cookie'    => true,
    'session'   => true,
    'database'  => true,
    'filter'    => function($input) { return true; },
    'sanitizer' => function($input) { return $input; },
  );
};

将抛出unexpected T_FUNCTION语法错误,并且数组是否为静态无关紧要。我绝望了,尝试了“老”的做法:

class Stuff {
  private $_preference_defaults = array(
    'cookie'    => true,
    'session'   => true,
    'database'  => true,
    'filter'    => create_function('$input', 'return true;'),
    'sanitizer' => create_function('$input', 'return $input;'),
  );
};

这导致unexpected '(', expecting ')'语法错误。但是,如果我提前定义函数, 工作:

class Stuff {
  function _preference_default_filter($input) {
    return true;
  }
  function _preference_default_sanitizer($input) {
    return true;
  }
  private $_preference_defaults = array(
    'cookie'    => true,
    'session'   => true,
    'database'  => true,
    'filter'    => _preference_default_filter,
    'sanitizer' => _preference_default_sanitizer,
  );
};

然后我可以在类方法中调用这些函数:

function do_stuff($foo) {
  return $this->{$this->_preference_defaults['filter']}($foo);
}

这不仅在语法上是酸的,在我的头脑中它的风格很糟糕,我可以想象这种诡计会在将来引起头痛。

  1. 我无法在类(静态)范围内创建匿名函数吗? (我想也许是因为无法在该上下文中创建有效的Closure对象?)
  2. 还有更多...... PHP ...意味着同一个目的吗?也就是说,是否有一种“更好”的方法将简单的默认回调分配给类范围中的数组值?我提供的最终片段肯定会完成工作,但我更喜欢一种不会让验光师要求更强处方的解决方案。

3 个答案:

答案 0 :(得分:1)

  

我无法在类(静态)范围内创建匿名函数吗? (我想也许是因为无法在该上下文中创建有效的Closure对象?)

是的,因为在解析步骤中应该知道类属性的初始值,而函数调用和匿名函数需要运行时

另请参阅此处以获取其他详细信息:https://stackoverflow.com/a/9029556/251311

无法得到你的第二个问题:-S

答案 1 :(得分:1)

这确实行不通。在演讲阶段,你可以做一些奇特的事情。

但是..因为你的属性只是私有的,而不是静态的..只需在构造函数中声明一切。问题解决了!

此语法:

'sanitizer' => _preference_default_sanitizer,

非常糟糕..使用E_NOTICE,您实际上会发现它首先将_preference_default_sanitizer转换为字符串,这就是可能工作的原因。

答案 2 :(得分:0)

只需将方法名称设置为字符串。

class Stuff {  
  private $_preference_defaults = array(
    'cookie'    => true,
    'session'   => true,
    'database'  => true,
    'filter'    => '_preference_default_filter',
    'sanitizer' => '_preference_default_sanitizer',
  );

  function _preference_default_filter($input) {
    return true;
  }

  function _preference_default_sanitizer($input) {
    return true;
  }
};

然后致电:

function do_stuff($foo) {
  return $this->{$this->_preference_defaults['filter']}($foo);
}

function do_stuff($foo) {
  return call_user_func(array($this, $this->_preference_defaults['filter']), $foo);
}