Синтаксический сахар PHP: как применить функцию к заданному входу несколько раз?

Из базы данных я получаю текст, где функция htmlentities() был применен четыре раза. Пример текста:

скидки &Amp; Amp; Amp; мастерские

Чтобы декодировать этот текст, мне нужно сделать следующее:

$out = html_entity_decode(html_entity_decode(html_entity_decode(html_entity_decode("specials & workshops"))));

Результат:

скидки & мастерские

Есть ли в PHP естественный способ написать это более эффективно?

-1

Решение

Мне нравится делать это рекурсивно так, чтобы мне не нужно было знать, сколько сущностей нужно сопоставить.

$string = 'specials & workshops';
$entity = '/&/';

function recurseHTMLDecode($str, $entity) {
preg_match($entity, $str, $matches);
echo count($matches);
if(1 == count($matches)) {
$str =  html_entity_decode($str);
$str = recurseHTMLDecode($str, $entity);
return $str;
} else {
return $str;
}

}

var_dump(recurseHTMLDecode($string, $entity));

Это возвращает:

11110 строка (20) & мастерские»

Здесь ПРИМЕР

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

2

Другие решения

Почему бы не объявить функцию для этого?

$in = "specials & workshops";

$decode = function($in) {
foreach(range(1,4) as $x) $in = html_entity_decode($in); return $in; };

function decode($in) {
foreach(range(1,4) as $x)
$in = html_entity_decode($in);
return $in;
}

// inline
$out = $decode($in);

// traditional
$out = decode($in);
1

Согласно рекурсивной идее @JayBlanchard я не создал следующее — очень нравится:

/**
* Apply a function to a certain input multiple times.
*
* @param $input: The input variable:
* @param callable $func: The function to call.
* @param int $times: How often the function should be called. -1 for deep call (unknown number of calls required). CAUTION: If output always changes this results in an endless loop.
* @return mixed
*/
function recapply($input,callable $func,int $times) {
if($times > 1) {
return recapply($func($input),$func,$times - 1);
} else if($times == -1) {
$res = $func($input);
if($res === $input) {
return $input;
} else {
return recapply($res,$func,-1);
}
}
return $func($input);
}

Рабочий пример вызова:

echo recapply("specials & workshops","html_entity_decode",4);
1
По вопросам рекламы [email protected]