PHP中将HTML的行内样式抽离为内嵌样式或者外联样式

<?php

/**
* 说明:
* 最近为了优化页面容量,需要将内嵌,行内样式,脚本等抽离成外联调用方式,一个个检查明显是
* 工作量浩大,花了一个下午时间写个脚本自动检查,配合使用。
*
* 功能:将行内样式抽离成内嵌样式,自动重命名元素的样式名
**/
function extractionInlineStyle( $url = 'http://www.163.com/' )
{
$content = file_get_contents( $url );

// 1.将行内样式抽离出来
preg_match_all( '/style=(\"|\')?([^\"\']*)(\"|\')?/', $content, $matchs );
// 1.1.去掉空格,md5生成类名
// 1.2.删除原码,替换类名
$styleStrings = '<style>';
//
$classCountNum = 1;
foreach( $matchs[0] as $stylekey=>$styleitem )
{
$styleNameMd5[ $stylekey ] = md5( $styleitem );
$styleNameID[ $stylekey ] = 'c_'.$classCountNum;
if( !isset($styleItems[ $styleNameMd5[ $stylekey ] ]) )
{
$styleItems[ $styleNameMd5[ $stylekey ] ] = $styleNameID[ $stylekey ];
$styleName[ $stylekey ] = "class={$matchs[1][$stylekey]}{$styleNameID[ $stylekey ]}{$matchs[3][$stylekey]}";
$styleStrings .= '.'.$styleNameID[ $stylekey ].'{'.str_ireplace(array("\r","\n"),'',$matchs[2][$stylekey]).'}';
$classCountNum++;
}else{
$styleName[ $stylekey ] = "class={$matchs[1][$stylekey]}{$styleItems[ $styleNameMd5[ $stylekey ] ]}{$matchs[3][$stylekey]}";
}
}
//
$styleStrings .= '</style>';
$styleStrings = preg_replace( '/\s\s+/', '', $styleStrings );
$content = str_ireplace( '</head>', $styleStrings."\n".'</head>', $content );
$content = str_ireplace( $matchs[0], $styleName, $content );

// 2.处理重复的class属性,只能处理class X 2的
// 2.1 将重复的第二个class删除
// 2.2 将重复的class内的值合并到第一个class中
preg_match_all( '/<([^>]*)class=(?<pclass1>(\"|\')(?<pclass11>([^\"\']*))(\"|\'))([^>]*)(?<=class)=(?<pclass2>(\"|\')(?<pclass22>([^\"\']*))(\"|\'))([^>]*)>/', $content, $matchsClass );
$strRepl = $matchsClass[0];
foreach( $strRepl as $sFkey=>$sFval )
{
$find = array(
0=>' class='.$matchsClass['pclass2'][$sFkey],
1=>' class='.$matchsClass['pclass1'][$sFkey],
);
$repl = array(
0=>'',
1=>' class="'.$matchsClass['pclass11'][$sFkey].' '.$matchsClass['pclass22'][$sFkey].'"'
);
$strRepl[ $sFkey ] = str_ireplace( $find, $repl, $sFval );
}
//
$content = str_ireplace( $matchsClass[0], $strRepl, $content );

exit( $content );
}

发表评论