PHP MVC渲染时如何实现含默认模板的全页面HTML压缩
问题原因
现有代码出现两个异常的核心原因有三点:
minifyContent()为返回值设计,调用时未用变量接收返回结果,视图内容的压缩结果被直接丢弃,实际未生效。- 输出缓冲仅包裹了视图文件加载逻辑,默认模板文件在缓冲关闭后才引入,这部分内容直接输出到浏览器,完全没有进入压缩处理流程。
- 未对全页面输出做统一接管,模板输出、未被正确处理的视图内容同时向外发送,就会出现页面内容重复输出两次的问题。
修正代码
调整render方法的缓冲逻辑,等视图、模板全部渲染完成拿到完整HTML后,再统一执行压缩,最后一次性输出压缩后的结果,从根源避免部分内容未压缩、重复输出的问题:
public static function render($filePath, $data = array()){ extract($data); // 加载视图内容并存入变量 ob_start(); require_once("mvc/view/" . $filePath); $content = ob_get_clean(); // 加载模板文件,接管全页面输出 ob_start(); require_once("theme/default.php"); $fullHtml = ob_get_clean(); // 压缩全页面内容后输出 echo minifyContent($fullHtml); }
压缩函数优化建议
原有压缩规则会误清除<pre>、<textarea>标签内的有效空白,导致代码块格式错乱、多行文本框内容异常,可对压缩函数做如下调整,跳过这些需要保留格式的区块:
function minifyContent($content){ // 暂存需要保留格式的标签内容 $reserved = []; $content = preg_replace_callback( '/<(pre|textarea|script|style)[^>]*>.*?<\/\\1>/is', function($match) use (&$reserved) { $key = '###RESERVED_BLOCK_' . count($reserved) . '###'; $reserved[$key] = $match[0]; return $key; }, $content ); // 执行原有压缩逻辑 $search = array( '/\>[^\S ]+/s', '/[^\S ]+\</s', '/(\s)+/s' ); $replace = array( '>', '<', '\\1' ); $content = preg_replace($search, $replace, $content); // 还原暂存的标签内容 return str_replace(array_keys($reserved), array_values($reserved), $content); }
内容的提问来源于stack exchange,提问作者user18413646
相关产品推荐
相关产品推荐

