Php 用于向HTML文档中的.js和.css引用添加版本号的正则表达式

Php 用于向HTML文档中的.js和.css引用添加版本号的正则表达式,php,html,regex,reference,replace,Php,Html,Regex,Reference,Replace,我有一个HTML文档,我想自动将版本号添加到所有脚本和样式表引用中 应更换以下部件: <link ... href="file.css" media="all" /> <script ... src="file.js"></script> <script ... src="http://myhost.com/file.js"></script> 但这并不是100%起作用,我相信有更好的方法可以做到这一点。 你会怎么写 编辑: 我

我有一个HTML文档,我想自动将版本号添加到所有脚本和样式表引用中

应更换以下部件:

 <link ... href="file.css" media="all" />
 <script ... src="file.js"></script>
 <script ... src="http://myhost.com/file.js"></script>
但这并不是100%起作用,我相信有更好的方法可以做到这一点。 你会怎么写

编辑:

我现在使用DOMDocument,但结果是速度非常慢

    <?php
//------- snip --------------
            $host       = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
            $refs       = array();
            $version    = "v". $version;
            $doc        = new DOMDocument();        
            $tmpDoc     = $html;

            $doc->loadHTML($tmpDoc);        
            $xpath = new DOMXPath($doc);
            foreach($xpath->query('/html/head/link/@href') as $href) {
                $ref = $href->value;
                if(
                    !preg_match('/^https?:/', $ref) || 
                    strpos($ref, $host) === 0               
                ) {
                    $refs[$ref] = preg_replace('/\.css$/', '.'.$version.'$0', $ref);
                }
            }
            foreach ($xpath->query('//script/@src') as $src) {
                $ref = $src->value;
                if(
                    !preg_match('/^https?:/', $ref) ||
                    strpos($ref, $host) === 0
                ) {
                    $refs[$ref] = preg_replace('/\.js$/', '.'.$version.'$0', $ref);
                }
            }       
            $html = str_replace(
                        array_keys($refs), 
                        array_values($refs), 
                        $tmpDoc
                    );
//------- snip --------------
    ?>

不要使用正则表达式,至少不要查找src值。使用DOM

var allScriptTags = document.getElementsByTagName("script");
var allLinkTags = document.getElementsByTagName("link");

for(var i=0; i<allScriptTags.length; i++) {
    var srcAttribute = allScriptTags[i].getAttribute("src");

    // ... do something with srcAttribute ...

    // replace it with the modified value
    allScriptTags[i].setAttribute("src", srcAttribute);
}

不要使用正则表达式,至少不要查找src值。使用DOM

var allScriptTags = document.getElementsByTagName("script");
var allLinkTags = document.getElementsByTagName("link");

for(var i=0; i<allScriptTags.length; i++) {
    var srcAttribute = allScriptTags[i].getAttribute("src");

    // ... do something with srcAttribute ...

    // replace it with the modified value
    allScriptTags[i].setAttribute("src", srcAttribute);
}

您最好使用类似或的HTML解析器来查找元素/属性。然后可以使用正则表达式修改属性值

下面是DOMDocument的一个示例:

$version = 'v123456';
$doc = new DOMDocument();
$doc->loadHTML($code);
$xpath = new DOMXPath($doc);
foreach ($xpath->query('/html/head/link/@href') as $href) {
    if (!preg_match('/^https?:/', $href->value)) {
        $href->value = preg_replace('/\.css$/', '.'.$version.'$0', $href->value);
    }
}
foreach ($xpath->query('//script/@src') as $src) {
    if (!preg_match('/^https?:/', $src->value)) {
        $src->value = preg_replace('/\.js$/', '.'.$version.'$0', $src->value);
    }
}

您最好使用类似或的HTML解析器来查找元素/属性。然后可以使用正则表达式修改属性值

下面是DOMDocument的一个示例:

$version = 'v123456';
$doc = new DOMDocument();
$doc->loadHTML($code);
$xpath = new DOMXPath($doc);
foreach ($xpath->query('/html/head/link/@href') as $href) {
    if (!preg_match('/^https?:/', $href->value)) {
        $href->value = preg_replace('/\.css$/', '.'.$version.'$0', $href->value);
    }
}
foreach ($xpath->query('//script/@src') as $src) {
    if (!preg_match('/^https?:/', $src->value)) {
        $src->value = preg_replace('/\.js$/', '.'.$version.'$0', $src->value);
    }
}

为什么不做一些更简单的事情,比如:

$version = 12345;
function print_local_css($base_filename)
{
    global $version;
    print '<link rel="stylesheet" type="text/css" href="'.$base_filename.'.v'.$version.'.css" />';
}

function print_local_js($base_filename)
{
    global $version;
    print '<script type="text/javascript" src="'.$base_filename.'.v'.$version.'.js"></script>';
}

它会很快,一个位置改变版本和任何你不想被版本控制的文件,只需手动将HTML放入

为什么不做一些更简单的事情,比如:

$version = 12345;
function print_local_css($base_filename)
{
    global $version;
    print '<link rel="stylesheet" type="text/css" href="'.$base_filename.'.v'.$version.'.css" />';
}

function print_local_js($base_filename)
{
    global $version;
    print '<script type="text/javascript" src="'.$base_filename.'.v'.$version.'.js"></script>';
}


它会很快,一个位置改变版本和任何你不想被版本控制的文件,只需手动将HTML放入

好吧,那也行,但是表演怎么样?我必须在每次加载页面时都这样做,而缓存在我的情况下是没有选择的。@Alex:我想你必须试一试。谢谢,我试过了。它所做的替换是正确的,但它改变了我的页面结构。删除某些位置上的空白,并删除某些标记上的结束标记。例如,获取。可能它没有正确检测到我的doctype。我将尝试一下简单的HTMLDOM解析器@亚历克斯:你如何输出修改过的文档?我做了$html=$doc->saveHTML;好吧,那也行,但是表演怎么样?我必须在每次加载页面时都这样做,而缓存在我的情况下是没有选择的。@Alex:我想你必须试一试。谢谢,我试过了。它所做的替换是正确的,但它改变了我的页面结构。删除某些位置上的空白,并删除某些标记上的结束标记。例如,获取。可能它没有正确检测到我的doctype。我将尝试一下简单的HTMLDOM解析器@亚历克斯:你如何输出修改过的文档?我做了$html=$doc->saveHTML;不幸的是,我对文档的创建方式没有太大的影响,我可以在输出到客户端之前浏览文档。不幸的是,我对文档的创建方式没有太大的影响,我可以在输出到客户端之前浏览文档。谢谢你,但我需要PHP-我不认为API与PHPDOM解析器有太大的不同-我认为API不应该与PHP Dom解析器有太大不同。您可以将.css的快速简单字符串替换为.12345.css,也可以进行正确的Dom解析、遍历和重新序列化。不能两者兼得:这种后处理不是一项简单的任务。如果您需要快速和正确,您必须更改生成此标记的模板。您可以将.css的快速简单字符串替换为.12345.css,也可以进行正确的DOM解析、遍历和重新序列化。不能两者兼得:这种后处理不是一项简单的任务。如果需要快速和正确的标记,则必须更改生成此标记的模板。