PHP bufffer输出minify,而不是textareapre。

问题描述 投票:2回答:5

我正在使用缓冲区消毒器,就像在PHP手册上看到的那样,但是在处理textareas中的双换行时遇到了问题。

当从我的数据库中提取一个包含双倍三倍换行符的字符串,并把它放到一个叫做 textarea,新行减少到只有一个新行。

因此。能否让函数排除所有的输出,包括 <pre>, <textarea></pre>, </textarea>?

看到这个问题。如何在不删除IE条件注释的情况下对php html输出进行最小化?我想我需要使用 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 以获得尽可能小的尺寸。

php preg-replace preg-match minify
5个回答
6
投票

这里是评论中提到的函数的实现。

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;
}

总是有优化的空间,但这是可行的。


0
投票

有一个简单的解决方案 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>

视觉输出

enter image description hereenter image description here


0
投票

这是我的sanitize HTML版本。我对代码做了注释,所以应该很清楚它在做什么。

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
© www.soinside.com 2019 - 2024. All rights reserved.