Я разрабатываю мини-фрейм 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 ()». Но удовольствие должно быть анонимным методом!
вы не можете использовать любую функцию через свойство класса.
function getCell($row) { # This line works $fun = $this->fun; return $this->alg . $fun($row) . "</td>"; }
делает ваш скрипт запущенным :), протестирован на php 5.3.1
Еще короче и, на мой взгляд, более элегантное решение:
function getCell($row) { return "{$this->alg}{$this->fun->__invoke($row)}</td>"; }
Неважно. Я нашел уродливое, но в конечном итоге рабочее решение:
$func = $this->fun; return "{$this->alg}{$func($row)}</td>";
Я не уверен, что вы пытаетесь выполнить, но разве вам не лучше использовать Magic Methods http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods ?
Один из способов сделать это:
call_user_func($this->fun, $row)
Я полагаю, что это вопрос стиля, но много времени с помощью call_user_func()
или call_user_func_array()
считается более чистым, чем синтаксис $func()
, а в некоторых случаях (например, этот) необходимо. Это также упрощает определение динамических вызовов сразу.
Я думаю, вам нужно
$this->$fun($row)
скорее, чем
$this->fun($row)
Первый вызов указателя функции хранится в переменной-члене $fun
, а последний вызывает функцию-член fun()
, которая, как указано, не существует.