【问题标题】:Question regarding anonymous methods as class members关于匿名方法作为类成员的问题
【发布时间】:2011-01-14 00:02:06
【问题描述】:

我正在开发一个 PHP 迷你框架,其中一个方法从对象数组构建 HTML 表格:

class HTMLTableField {
    private $hdr;
    private $alg;
    private $fun;

    function __construct($descr, $align, $apply) {
        # fun must be an anonymous function
        $this->hdr = '<th>' . htmlentities($descr) . "</th>\n";     
        $this->alg = "<td style=\"text-align: {$align}\">";
        $this->fun = $apply;
    }

    function getHeader() {
        return $this->hdr;
    }

    function getCell($row) {
        # This line fails
        return "{$this->alg}{$this->fun($row)}</td>";
    }
}

function gen_html_table($rows, $fields) {
    # $fields must be an array of HTMLTableField objects
    echo "<table>\n<thead>\n<tr>\n";
    foreach ($fields as $field)
        echo $field->getHeader();
    echo "</tr>\n</thead>\n<tbody>\n";
    foreach ($rows as $row) {
        echo "<tr>\n";
        foreach ($fields as $field)
            echo $field->getCell($row);
        echo "</tr>\n";
    }
    echo "</tbody>\n</table>\n";
}

但是,当gen_html_table的控制流到达

echo $field->getCell($row);

我收到一个错误:“调用未定义的方法 HTMLTableField::fun()。”不过 fun 应该是匿名的方法!

【问题讨论】:

    标签: php anonymous-methods


    【解决方案1】:

    还有更短且在我看来更优雅的解决方案:

    function getCell($row) {
        return "{$this->alg}{$this->fun->__invoke($row)}</td>";
    }
    

    【讨论】:

      【解决方案2】:

      你不能通过类属性来使用任何恶意函数。

      function getCell($row) {
          # This line works
          $fun = $this->fun;
          return $this->alg . $fun($row) . "</td>";
      }
      

      让你的脚本运行 :),在 php 5.3.1 上测试

      【讨论】:

      • 是的,这就是我刚刚所做的。但它不是很优雅。
      • 比起call_user_func(),我更喜欢阅读它。遗憾的是没有更好的方法。
      • 是的,call_user_func() 让人感觉好像反射不是 PHP 原生的,而是被入侵的。
      【解决方案3】:

      没关系。我找到了一个丑陋但最终可行的解决方案:

      $func = $this->fun;
      return "{$this->alg}{$func($row)}</td>";
      

      【讨论】:

        【解决方案4】:

        我不确定你想要完成什么,但使用魔术方法http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods 不是更好吗?

        【讨论】:

        • 不,这一次魔法方法没有用。 fun 是一个匿名函数。
        【解决方案5】:

        一种方法是:

        call_user_func($this->fun, $row)
        

        我想这是风格问题,但很多时候使用call_user_func()call_user_func_array() 被认为比$func() 语法更干净,在某些情况下(例如这个),这是必要的。它还可以更轻松地立即发现动态调用。

        【讨论】:

        • 是的,但我希望$($this-&gt;fun)($row) 是可能的。
        • @Eduardo call_user_func[_array] 是 PHP 方式。
        • 我是一名 C++ 程序员,碰巧在必要时使用 PHP。 FORTRAN 程序员可以用任何语言编写 FORTRAN 程序。 C++ 程序员讨厌所有其他语言,因为他不能用它们编写 C++ 程序。
        【解决方案6】:

        我认为你需要

        $this->$fun($row)
        

        而不是

        $this->fun($row)
        

        前者调用存储在成员变量$fun中的函数指针,而后者调用成员函数fun(),指出不存在。

        【讨论】:

        • 哦。我以为 $fun 被用来使用 string 作为函数的名称。
        • @Eduardo,它也可以这样做,但绝对不推荐!
        • 我这个左脑C++程序员想用$($this-&gt;fun)
        • 实际上,我有点怀疑您的问题是您在引号内,这使字符串解析变得复杂。您是否尝试过将匿名函数调用整理到自己的行中?
        • 不。但是我尝试将匿名函数提取到一个临时变量中,这就像一个魅力。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-30
        • 2018-08-25
        • 2011-11-17
        相关资源
        最近更新 更多