Вопрос относительно анонимных методов в качестве членов класса - PullRequest
4 голосов
/ 14 января 2011

Я разрабатываю мини-фреймворк 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 ().» Но веселье должно быть анонимным методом!

Ответы [ 6 ]

2 голосов
/ 06 декабря 2011

Есть еще более короткое и, на мой взгляд, более элегантное решение:

function getCell($row) {
    return "{$this->alg}{$this->fun->__invoke($row)}</td>";
}
1 голос
/ 14 января 2011

вы не можете использовать любую функцию через свойство класса.

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

делает ваш скрипт запущенным :), протестировано на php 5.3.1

1 голос
/ 14 января 2011

Один из способов сделать это:

call_user_func($this->fun, $row)

Полагаю, это вопрос стиля, но много времени с использованием call_user_func() или call_user_func_array() считается чище, чем синтаксис $func(), ив некоторых случаях (таких как этот) необходимо.Это также облегчает обнаружение динамических вызовов сразу.

1 голос
/ 14 января 2011

Я не уверен, что вы пытаетесь достичь, но вам не лучше использовать магические методы http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods?

1 голос
/ 14 января 2011

Неважно.Я нашел уродливое, но в конечном итоге работающее решение:

$func = $this->fun;
return "{$this->alg}{$func($row)}</td>";
0 голосов
/ 14 января 2011

Я думаю, что вам нужно

$this->$fun($row)

вместо

$this->fun($row)

Первый вызывает указатель функции, хранящийся в переменной-члене $fun, а второй вызывает функцию-член fun(), который, как указано, не существует.

...