Отметьте вопрос и ответ:
Начиная с PHP5.3 вы можете использовать замыкания
или функторы для передачи методов
вокруг. До этого вы могли написать
анонимная функция с
create_function () , но это
довольно неловко.
Но то, что вы пытаетесь достичь, лучше всего решить, передав Объекты Фильтра вашему рендереру. Все фильтры должны использовать один и тот же метод, поэтому вы можете использовать его в виде шаблона стратегии, например, сначала напишите интерфейс:
interface Filter
{
public function filter($value);
}
Затем напишите ваши фильтры, реализующие интерфейс
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) . '…';
}
}
Дайте вашему ObjectTable метод приема фильтров
public function addFilter($field, Filter $filter)
{
if(in_array($field, $this->fields)) {
$this->_filters[$field][] = $filter;
}
return $this;
}
А когда вы создаете экземпляр 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);
Затем измените ваш метод render (), чтобы проверить, есть ли какие-либо фильтры, установленные для полей, которые вы отображаете, и вызовите для них метод 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
}
}
Таким образом, вы можете добавлять бесконечные фильтры.