Question regarding anonymous methods as class members
I am developing a PHP mini-framework, one of whose methods builds an HTML table from an array of objects:
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";
}
However, when the flow of control of gen_html_table
reaches
echo $field->getCell($row);
I get an error: "Call to undefined method HTMLTableField::fun()." But fun is supposed to be an anonymous method!
There is even shorter and in my opinion more elegant solution:
function getCell($row) {
return "{$this->alg}{$this->fun->__invoke($row)}</td>";
}
you can't use an anynomious function via the class property.
function getCell($row) {
# This line works
$fun = $this->fun;
return $this->alg . $fun($row) . "</td>";
}
makes your script running :), tested on php 5.3.1
Never mind. I found an ugly, but ultimately working solution:
$func = $this->fun;
return "{$this->alg}{$func($row)}</td>";
I'm not sure what you are try to accomplish but are you not better off using Magic Methods http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods?
One way to do this is:
call_user_func($this->fun, $row)
I suppose it's a matter of style, but a lot of time using call_user_func()
or call_user_func_array()
is considered cleaner than $func()
syntax, and in some cases (such as this one), necessary. It also makes it easier to spot dynamic calls right away.
I think you need
$this->$fun($row)
rather than
$this->fun($row)
The former calls the function pointer stored in the member variable $fun
, while the latter calls the member function fun()
, which as pointed out does not exist.
精彩评论