preg replace — минимизировать вывод PHP-буфера, а не textarea / pre

Я использую буферное дезинфицирующее средство, как видно из комментария к PHP, но у меня проблемы с двойными символами новой строки в textareas.

При извлечении строки из моей базы данных, содержащей двойные / тройные / четырехкратные переводы строк, и помещении ее в textareaсимволы новой строки сводятся только к одной строке.

Следовательно: возможно ли, чтобы функция исключала все выходные данные между <pre>, <textarea> а также </pre>, </textarea>?

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

Я использую функцию

function sanitize_output($buffer) {
$search = array(
'/\>[^\S ]+/s',  // strip whitespaces after tags, except space
'/[^\S ]+\</s',  // strip whitespaces before tags, except space
'/(\s)+/s'       // shorten multiple whitespace sequences
);

$replace = array(
'>',
'<',
'\\1'
);

$buffer = preg_replace($search, $replace, $buffer);

return $buffer;
}

ob_start("sanitize_output");

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

2

Решение

Вот реализация функции, упомянутой в комментариях:

function sanitize_output($buffer) {

// Searching textarea and pre
preg_match_all('#\<textarea.*\>.*\<\/textarea\>#Uis', $buffer, $foundTxt);
preg_match_all('#\<pre.*\>.*\<\/pre\>#Uis', $buffer, $foundPre);

// replacing both with <textarea>$index</textarea> / <pre>$index</pre>
$buffer = str_replace($foundTxt[0], array_map(function($el){ return '<textarea>'.$el.'</textarea>'; }, array_keys($foundTxt[0])), $buffer);
$buffer = str_replace($foundPre[0], array_map(function($el){ return '<pre>'.$el.'</pre>'; }, array_keys($foundPre[0])), $buffer);

// your stuff
$search = array(
'/\>[^\S ]+/s',  // strip whitespaces after tags, except space
'/[^\S ]+\</s',  // strip whitespaces before tags, except space
'/(\s)+/s'       // shorten multiple whitespace sequences
);

$replace = array(
'>',
'<',
'\\1'
);

$buffer = preg_replace($search, $replace, $buffer);

// Replacing back with content
$buffer = str_replace(array_map(function($el){ return '<textarea>'.$el.'</textarea>'; }, array_keys($foundTxt[0])), $foundTxt[0], $buffer);
$buffer = str_replace(array_map(function($el){ return '<pre>'.$el.'</pre>'; }, array_keys($foundPre[0])), $foundPre[0], $buffer);

return $buffer;
}

Всегда есть место для оценки, но это работает

6

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

Существует простое решение для PRE это не работает для TEXTAREA: заменить пробелы на &nbsp; затем используйте nl2br() заменить символы новой строки BR элементы перед выводом значений. Это не элегантно, но работает:

<pre><?php
echo(nl2br(str_replace(' ', '&nbsp;', htmlspecialchars($value))));
?></pre>

К сожалению, его нельзя использовать для TEXTAREA потому что браузеры отображают <br /> как текст

0

Может быть, это даст вам результат, который вам нужен.
Но в целом я не рекомендую такой вид дезинфекции, это не очень хорошо для производительности. В наши дни нет необходимости удалять пробельные символы из вывода html.

function sanitize_output($buffer) {
$ignoreTags = array("textarea", "pre");

# find tags that must be ignored and replace it with a placeholder
$tmpReplacements = array();
foreach($ignoreTags as $tag){
preg_match_all("~<$tag.*?>.*?</$tag>~is", $buffer, $match);
if($match && $match[0]){
foreach($match[0] as $key => $value){
if(!isset($tmpReplacements[$tag])) $tmpReplacements[$tag] = array();
$index = count($tmpReplacements[$tag]);
$replacementValue = "<tmp-replacement>$index</tmp-relacement>";
$tmpReplacements[$tag][$index] = array($value, $replacementValue);
$buffer = str_replace($value, $replacementValue, $buffer);
}
}
}

$search = array(
'/\>[^\S ]+/s',  // strip whitespaces after tags, except space
'/[^\S ]+\</s',  // strip whitespaces before tags, except space
'/(\s)+/s'       // shorten multiple whitespace sequences
);

$replace = array(
'>',
'<',
'\\1'
);

$buffer = preg_replace($search, $replace, $buffer);

# re-insert previously ignored tags
foreach($tmpReplacements as $tag => $rows){
foreach($rows as $values){
$buffer = str_replace($values[1], $values[0], $buffer);
}
}

return $buffer;
}
0

function nl2ascii($str){
return str_replace(array("\n","\r"), array("&#10;","&#13;"), $str);
}

$StrTest = "test\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\rtest";

ob_start("sanitize_output");
?>

<textarea><?php echo nl2ascii($StrTest); ?></textarea>
<textarea><?php echo $StrTest; ?></textarea>

<pre style="border: 1px solid red"><?php echo nl2ascii($StrTest); ?></pre>
<pre style="border: 1px solid red"><?php echo $StrTest; ?></pre>

<?php
ob_flush();

сырая продукция

      <textarea>test&#10;&#13;&#10;&#13;&#10;&#13;&#10;&#13;&#10;&#13;&#10;&#13;&#10;&#13;&#10;&#13;&#10;&#13;test</textarea>
<textarea>test
test</textarea>

<pre style="border: 1px solid red">test&#10;&#13;&#10;&#13;&#10;&#13;&#10;&#13;&#10;&#13;&#10;&#13;&#10;&#13;&#10;&#13;&#10;&#13;test</pre>
<pre style="border: 1px solid red">test
test</pre>

визуальный вывод

введите описание изображения здесь
введите описание изображения здесь

0
По вопросам рекламы [email protected]