Я использую буферное дезинфицирующее средство, как видно из комментария к 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
чтобы получить наименьший возможный размер.
Вот реализация функции, упомянутой в комментариях:
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;
}
Всегда есть место для оценки, но это работает
Существует простое решение для PRE
это не работает для TEXTAREA
: заменить пробелы на
затем используйте nl2br()
заменить символы новой строки BR
элементы перед выводом значений. Это не элегантно, но работает:
<pre><?php
echo(nl2br(str_replace(' ', ' ', htmlspecialchars($value))));
?></pre>
К сожалению, его нельзя использовать для TEXTAREA
потому что браузеры отображают <br />
как текст
Может быть, это даст вам результат, который вам нужен.
Но в целом я не рекомендую такой вид дезинфекции, это не очень хорошо для производительности. В наши дни нет необходимости удалять пробельные символы из вывода 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;
}
function nl2ascii($str){
return str_replace(array("\n","\r"), array(" "," "), $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 test</textarea>
<textarea>test
test</textarea>
<pre style="border: 1px solid red">test test</pre>
<pre style="border: 1px solid red">test
test</pre>
визуальный вывод