PHP Buffer输出缩小,而不是textarea/pre

PHP Buffer输出缩小,而不是textarea/pre,php,preg-replace,preg-match,minify,Php,Preg Replace,Preg Match,Minify,我正在使用缓冲区消毒剂,如PHP手册中的注释所示,但在文本区域中使用双换行时遇到问题 当从我的数据库中拉出一个包含双/三/四个换行符的字符串,并将其放入textarea中时,换行符会减少到只有一个换行符 function sanitize_output($buffer) { // Searching textarea and pre preg_match_all('#\<textarea.*\>.*\<\/textarea\>#Uis', $buffer

我正在使用缓冲区消毒剂,如PHP手册中的注释所示,但在文本区域中使用双换行时遇到问题

当从我的数据库中拉出一个包含双/三/四个换行符的字符串,并将其放入
textarea
中时,换行符会减少到只有一个换行符

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;
}
因此:是否可以让函数排除

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
来获得尽可能小的尺寸。

对于
PRE
有一个简单的解决方案,它不适用于
TEXTAREA
:用
替换空格,然后使用
nl2br()
在输出值之前,用
BR
元素替换换行符。虽然不雅致,但很管用:



不幸的是,它不能用于
TEXTAREA
,因为浏览器将

显示为文本。

以下是注释中提到的功能的实现:

      <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>
function sanitize\u输出($buffer){
//搜索文本区域和预处理
preg#u match#u all('.\.\#Uis',$buffer,$foundTxt);
preg#u match#u all('.\.\#Uis',$buffer,$foundPre);
//将两者替换为$index/$index
$buffer=str_replace($foundTxt[0],数组_映射(函数($el){return'.$el.';},数组_键($foundTxt[0]),$buffer);
$buffer=str_replace($foundPre[0],数组_映射(函数($el){return'.$el.';},数组_键($foundPre[0]),$buffer);
//你的东西
$search=array(
'/\>[^\S]+/S',//除去标记后的空格,空格除外
“/[^\S]+\”,
“
函数nl2ascii($str){
返回str#u replace(数组(“\n”、“\r”)、数组(“
;”、“
;”,$str);
}
$StrTest=“test\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\rtest”;
ob_启动(“消毒_输出”);
?>

也许这会给你你想要的结果。 但总的来说,我不推荐这种清理作业,它对性能不好。在现在,真的不需要从html输出中剥离空白字符

function sanitize\u输出($buffer){
$ignoreTags=数组(“textarea”、“pre”);
#查找必须忽略的标记并将其替换为占位符
$tmpReplacements=array();
foreach($ignoreTags作为$tag){
preg_match_all(“~.*is”,$buffer,$match);
如果($match&&$match[0]){
foreach($key=>$value时匹配[0]as$key){
如果(!isset($tmpReplacements[$tag]))$tmpReplacements[$tag]=array();
$index=count($tmpReplacements[$tag]);
$replacementValue=“$index”;
$tmpReplacements[$tag][$index]=数组($value,$replacementValue);
$buffer=str_replace($value,$replacementValue,$buffer);
}
}
}
$search=array(
'/\>[^\S]+/S',//除去标记后的空格,空格除外
“/[^\S]+\”,

“这是我的清理HTML版本。我已经对代码进行了注释,所以应该清楚它在做什么

函数压缩程序($html='',$arr_tags=['textarea','pre'])){
$arr_found=[];
$arr_back=[];
$arr_temp=[];
//foreach标记获取带有标记及其内容的数组
//数组类似于:$arr_temp[0]=[0=['content'];
foreach($arr_标记为$tag){
if(preg#u match#u all('.\.\#Uis',$html,$arr#u temp)){
//标签是存在的
foreach($arr\u temp as$key=>$arr\u item){
//对于标签的每一项,保留该项
$arr_找到[$tag][]=$arr_项[0];
//制作一个nmubered替换1
$arr_back[$tag][]=''.$key';
}
//用编号的标签替换所有现有标签
$html=str_replace((数组)$arr_found[$tag],(数组)$arr_back[$tag],$html);
}
}//结束foreach
//清除html
$arr\u搜索=[
'/\>[^\S]+/S',//除去标记后的空格,空格除外
“/[^\S]+\”,

'如果你没有时间,有一个非常愚蠢的解决方案:preg_将每个文本区域和每个pre之间的所有内容替换为随机字符串(将原始内容保存在数组中(随机字符串='原始内容');然后运行你的过程,然后preg将其替换回来(随机字符串->数组('随机字符串');您可以轻松地实现它,并等待更好的答案。如果您可以等待,请等待,因为这是一个非常丑陋的解决方案:)。只是一个随机想法(我没有测试它):编写一个函数,给定一个字符串,将其放入列表并返回一个唯一的ID(列表f.e中的索引)。使用该函数“输出”要放入
元素中的字符串。让minifier ob处理程序完成其工作,然后获取其输出,识别
textarea
元素,并用以前保存的文本替换ID。查找类似
1
的内容要比删除空格容易得多;即使不使用
regex
(但使用它们更容易)。将列表和函数打包到一个类中,您就可以开始了。@axiac这基本上是第一个注释的方法,我以前没有读过。现在我看到它非常相似。Jacek的建议是在运行问题中显示的函数之前识别和提取字符串。我的建议是不要将它们放在第一个pl的输出中ace。只是想一想:我不知道你为什么想用HTML对这些作业进行清理,但一般来说,用这种技术压缩HTML并没有什么特别的需要。对于你的问题没有真正简单的解决方案,也许这会产生你并不真正需要的巨大开销。也许没有清理功能,你的网站服务速度会更快。你应该考虑一下,也许可以在你的特定网站上测试一下它的好处。你可以用更多的代码来做到这一点:
$textWithBr=nl2br(str_replace('''',,htmlspecialchars($value));
$text=str_replace('
,'\n',$textWithBr);
我想要一个u
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>
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 comprimeer($html = '', $arr_tags = ['textarea', 'pre']) {
    $arr_found = [];
    $arr_back = [];
    $arr_temp = [];

    // foreach tag get an array with tag and its content
    // the array is like: $arr_temp[0] = [ 0 = ['<tag>content</tag>'] ];
    foreach ($arr_tags as $tag) {
        if(preg_match_all('#\<' . $tag . '.*\>.*\<\/' . $tag . '\>#Uis', $html, $arr_temp)) {
            // the tag is present
            foreach($arr_temp as $key => $arr_item) {
                // for every item of the tag keep the item
                $arr_found[$tag][] = $arr_item[0];
                // make an nmubered replace <tag>1</tag>
                $arr_back[$tag][] = '<' . $tag . '>' . $key . '</' . $tag . '>';
            }
            // replace all the present tags with the numbered ones
            $html = str_replace((array) $arr_found[$tag], (array) $arr_back[$tag], $html);
        }
    } // end foreach

    // clean the html
    $arr_search = [
        '/\>[^\S ]+/s', // strip whitespaces after tags, except space
        '/[^\S ]+\</s', // strip whitespaces before tags, except space
        '/(\s)+/s'     // shorten multiple whitespace sequences
    ];
    $arr_replace = [
        '>',
        '<',
        '\\1'
    ];
    $clean = preg_replace($arr_search, $arr_replace, $html);

    // put the kept items back
    foreach ($arr_tags as $tag) {
        if(isset($arr_found[$tag])) {
            // the tag was present replace them back
            $clean = str_replace($arr_back[$tag], $arr_found[$tag], $clean);
        }   
    } // end foreach
    // give the cleaned html back
    return $clean;
} // end function