我上了课.我给它一些对象(主要是retreived数据库行)作为输入,并告诉它必须显示哪些字段,以及我想要的按钮.然后它呈现一个非常好的html表!我想,这真是太棒了.
$ot = new ObjectTable();
$ot->objects = $some_objects;
$ot->fields = array('id','name','description','image');
$ot->buttons = array('edit','delete');
$ot->render();
Run Code Online (Sandbox Code Playgroud)
但是,我也希望能够操纵它显示的数据.例如,我希望能够截断"描述"字段.或者显示图像缩略图(而不是'picture.jpg'作为文本).我不知道如何将这些函数传递给类.也许是这样的:
$ot->functions = array(null,null,'truncate','thumbnail');
Run Code Online (Sandbox Code Playgroud)
但后来我不知道如何转换这些字符串来运行一些实际的代码,或者如何传递参数.
必须有一个很好的方式来做我想要的.怎么样?
检查这个问题,答案是:
从PHP5.3开始,您可以使用闭包或仿函数来传递方法.在此之前,您可以使用create_function()编写一个匿名函数 ,但这很尴尬.
但是,您尝试实现的目标最好通过将过滤器对象传递给渲染器来解决.所有过滤器都应该使用相同的方法,因此您可以以策略模式的方式使用它,例如首先编写一个接口:
interface Filter
{
public function filter($value);
}
Run Code Online (Sandbox Code Playgroud)
然后编写实现该接口的过滤器
class TruncateFilter implements Filter
{
protected $_maxLength;
public function __construct($maxLength = 50)
{
$this->_maxLength = (int) $maxLength;
}
public function filter($value)
{
return substr(0, $this->_maxLength, $value) . '…';
}
}
Run Code Online (Sandbox Code Playgroud)
为ObjectTable提供一个接受过滤器的方法
public function addFilter($field, Filter $filter)
{
if(in_array($field, $this->fields)) {
$this->_filters[$field][] = $filter;
}
return $this;
}
Run Code Online (Sandbox Code Playgroud)
当你进行ObjectTable实例化时,请使用
$ot = new ObjectTable();
$ot->objects = $some_objects;
$ot->fields = array('id','name','description','image');
$ot->addFilter('description', new TruncateFilter)
->addFilter('name', new TruncateFilter(10))
->addFilter('image', new ThumbnailFilter);
Run Code Online (Sandbox Code Playgroud)
然后修改render()方法以检查是否为要渲染的字段设置了任何Filters,并对它们调用filter()方法.
public function render()
{
foreach($this->fields as $field) {
$fieldValue = // get field value somehow
if(isset($this->filters[$field])) {
foreach($this->filters[$field] as $filter) {
$fieldValue = $filter->filter($fieldValue)
}
}
// render filtered value
}
}
Run Code Online (Sandbox Code Playgroud)
这样您就可以添加无限过滤器.