Search code examples
phppreg-replacepreg-matchminify

PHP bufffer output minify, NOT textarea/pre


I'm using the buffer sanitizer, as seen in a PHP manual comment, but having trouble with double newlines in textareas.

When pulling a string out from my database, containing double/triple/quadruple newlines, and putting it into a textarea, the newlines are reduced to only a single newline.

Therefore: Is it possible to have the function exclude all output between <pre>, <textarea> and </pre>, </textarea>?

Seeing this question, How to minify php html output without removing IE conditional comments?, I think i need to use the preg_match, but I'm not sure how to implement it into this function.

The function I'm using is

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");

And yeah I'm using both this sanitizer and GZIP to get the smallest size possible.


Solution

  • here is an implementation of the function mentioned in the comments:

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

    There is always room for optimation but that works