2011-01-14 4 views
4

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

ответ

1

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

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

делает ваш скрипт работает :), испытано на PHP 5.3.1

+0

Да, это то, что я только что сделал. Но это не очень элегантно. – pyon

+0

Мне нравится читать его больше, чем 'call_user_func()'. к сожалению, нет лучшего способа. –

+0

Да, 'call_user_func()' заставляет чувствовать, что отражение не было родным для PHP, а скорее взломали его. – pyon

0

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

$this->$fun($row) 

вместо

$this->fun($row) 

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

+0

Oh. Я думал, что '$ fun' использовался для использования ** string ** в качестве имени функции. – pyon

+0

@ Эдуардо, он тоже может это сделать, но это определенно не рекомендуется! –

+0

@JSBangs: '$ this -> $ fun' тоже не работает. : S – pyon

1

Ничего. Я нашел некрасивый, но в конечном счете, рабочий раствор:

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

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

call_user_func($this->fun, $row) 

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

+0

Да, но я желаю '$ ($ this-> fun) ($ row)' были возможны. – pyon

+0

@Eduardo 'call_user_func [_array]' является способом PHP. – mfonda

+0

Я программист на C++, который, по-видимому, использует PHP по необходимости. Программист FORTRAN может писать программы FORTRAN на любом языке. Программист C++ ненавидит все остальные языки, потому что он не может писать в них программы на C++. – pyon

2

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

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