Php классы (я думаю)

Есть ли способ создать php-класс (или функцию), который «упрощает» это

ucfirst(str_replace('_',' ',html_entity_decode(trim($variable), ENT_QUOTES)))); 

Переменная $ может «прибывать» из любого места, например глобальная из другой функции или только «стандартная» переменная

Если вы используете его более одного раза, я бы определенно включил его в функцию. Таким образом, вы не будете повторять весь код.

 function functionName($input){ return ucfirst(str_replace('_',' ',html_entity_decode(trim($input), ENT_QUOTES))); } echo functionName($variable); 

Если вы хотите иметь это в классе (как следует из названия вопроса), вам следует создать классы фильтров. Это обычная вещь. Однако, по сравнению с простым вложением функций, это будет гораздо больше кода, чтобы сделать это правильно. Преимущество заключается в том, что вы можете легко расширять и комбинировать фильтры практически с любыми вашими фильтрационными потребностями.

Я быстро что-то взбесил.

 interface IFilter { /** * @param Mixed $value The value to be filtered * @return Mixed The filtered value */ public function filter($value); } 

Все фильтры должны реализовывать интерфейс IFilter . Это делается для того, чтобы убедиться, что всякий раз, когда вы используете фильтр, у него есть метод filter() который принимает один аргумент $value . Мы не можем принудительно вводить возвращаемые значения, но блок doc указал, что мы ожидаем, что он вернет отфильтрованное значение. Два очень простых фильтра выглядят так:

 class ucFirstFilter implements IFilter { public function filter($value) { return ucfirst($value); } } class TrimFilter implements IFilter { public function filter($value) { return trim($value); } } 

Это не что иное, как обертка объектов вокруг двух собственных функций PHP. Вы используете его следующим образом:

 $trimFilter = new TrimFilter; echo trimFilter->filter(' trim me '); // returns 'trim me' 

Два других фильтра несколько сложнее, потому что они могут быть переданы более чем одним аргументом:

 class SeparatorToSeparatorFilter implements IFilter { protected $_separator; protected $_replacement; public function __construct($separator = '_', $replacement = ' ') { $this->_separator = $separator; $this->_replacement = $replacement; } public function filter($value) { return str_replace($this->_separator, $this->_replacement, $value); } } class HtmlEntityDecodeFilter implements IFilter { protected $_quoteStyle; protected $_charset; public function __construct($quoteStyle=ENT_COMPAT, $charset='ISO-8859-1') { $this->_quoteStyle = $quoteStyle; $this->_charset = $charset; } public function filter($value) { return html_entity_decode($value, $this->_quoteStyle, $this->_charset); } } 

Как вы можете видеть, конфигурация дополнительных аргументов выполняется через конструктор. Я использовал некоторые значения по умолчанию, поэтому вам нужно только их предоставить, когда вам нужно отклоняться от них. В случае второго фильтра я использовал настройки по умолчанию для собственной функции. Вот как вы их используете:

 $trimFilter = new TrimFilter; $separatorFilter = new SeparatorToSeparatorFilter('-'); echo $separatorFilter->filter($trimFilter->filter(' trim-me ')); // returns 'trim me'; 

Теперь у вас может возникнуть соблазн добавить несколько фильтров в один класс фильтра. Dont. Каждый фильтр должен делать только одну вещь. Существует лучший способ объединения фильтров. Все, что вам нужно, это фильтр, который объединяет несколько других фильтров, например FilterChain:

 class FilterChain implements IFilter { protected $_filters; public function __construct() { $this->_filters = new SplObjectStorage; } public function chain(IFilter $filter) { $this->_filters->attach($filter); return $this; } public function remove(IFilter $filter) { $this->_filters->detach($filter); return $this; } public function filter($value) { foreach($this->_filters as $filter) { $value = $filter->filter($value); } return $value; } } 

FilterChain принимает любой объект, который реализует IFilter и если вы вызываете его методом filter() , он будет перебирать все связанные фильтры в порядке, в котором вы его chain() и возвращаете переданное $value :

 $filterChain = new FilterChain; $filterChain->chain(new ucFirstFilter) ->chain(new SeparatorToSeparatorFilter) ->chain(new HtmlEntityDecodeFilter(ENT_QUOTES, 'UTF-8')) ->chain(new TrimFilter); echo $filterChain->filter(' i am a "string_to_be_filtered" '); // outputs 'i am a "string to be filtered"' 

Поскольку FilterChain также реализует сам IFilter , вы также можете добавить его в другие FilterChains. Это композитный шаблон . Фильтр, указанный выше, можно записать в виде

 $chain1 = new FilterChain; $chain1->chain(new ucFirstFilter) ->chain(new SeparatorToSeparatorFilter); $chain2 = new FilterChain; $chain2->chain($chain1); $chain2->chain(new HtmlEntityDecodeFilter(ENT_QUOTES, 'UTF-8')) ->chain(new TrimFilter); 

Как вы можете видеть, это гораздо больше кода, но он также очень расширяем. Главное преимущество перед тем, чтобы иметь одну функцию, которая обертывает все собственные функции в одну функцию, – вы можете комбинировать все, что угодно. Если вы решили, что вам нужна другая функция, которая не использует функцию trim() , вам придется написать совершенно новую функцию, и вы случайно окажетесь с множеством функций и избыточным кодом для любой возможной комбинации фильтров. С FilterChain вы просто добавляете фильтры и фильтры. А поскольку FilterChain является объектом, вы можете свободно его передавать.

К счастью, такие библиотеки фильтров уже существуют, например, Zend_Filter предлагает ряд готовых фильтров и может использоваться автономно (например, без необходимости переноса вашего приложения на ZF).