-1

我正在解析一个外部文档并将其中的所有链接设为绝对链接。例如:

    <link rel="stylesheet" type="text/css" href="/css/style.css" />

将被替换为:

    <link rel="stylesheet" type="text/css" href="http://www.hostsite.com/css/style.css" />

其中http://www.hostsite.com是文档的基本 URL。

这是我尝试过但失败的:

    $linkfix1 = str_replace('href=\"\/', 'href=\"$url\/', $code);

网站上有几个问题与对单个 URL 字符串进行此替换有关,但我找不到任何适用于文档中嵌入的 URL 的问题。关于如何使所有这些链接成为绝对的,有什么好的建议吗?

4

2 回答 2

1

您不需要在使用单引号的字符串中转义双引号。

您也根本不需要转义正斜杠。

你只是想要:

str_replace('href="', 'href="http://hostsite.com', $replace_me);

为了安全起见,不要用主机站点替换每个链接:

str_replace('href="/css/', 'href="http://hostsite.com/css/', $replace_me);
于 2013-03-13T19:07:29.277 回答
0

公共服务公告:不要使用正则表达式重写格式化文档的元素。

执行此操作的正确方法是将文档加载为实体(DOMDocumentSimpleXMLElement)并根据节点和值进行处理。最初的解决方案也没有处理src基本相对 URL(例如/css/style.css)的标签或解析。

这是一个最合适的解决方案,如果需要可以扩展:

# Example URL
$url = "http://www.stackoverflow.com/";

# Get the root and current directory
$pattern = "/(.*\/\/[^\/]+\/)([^?#]*\/)?/";
/*  The pattern has two groups: one for the domain (anything before
    the first two slashes, the slashes, anything until the next slash,
    and the next slash) and one for the current directory (anything
    that isn't an anchor or query string, then the last slash before
    any anchor or query string).  This yields:
    - [0]: http://stackoverflow.com/question/123412341234
    - [1]: http://stackoverflow.com/
    - [2]: question/
    We only need [0] (the entire match) and [1] (just the first group).
*/
$matches = array();
preg_match($pattern, $url, $matches);
$cd = $matches[0];
$root = $matches[1];

# Normalizes the URL on the provided element's attribute
function normalizeAttr($element, $attr){
    global $pattern, $cd, $root;
    $href = $element->getAttribute($attr);
    # If this is an external URL, ignore
    if(preg_match($pattern, $href))
        return;
    # If this is a base-relative URL, prepend the base
    elseif(substr($href, 0, 1) == '/')
        $element->setAttribute($attr, $root . substr($href, 1));
    # If this is a relative URL, prepend the current directory
    elseif(substr($href, 0, strlen($cd)) != $cd)
        $element->setAttribute($attr, $cd . $href);
}

# Load in the data, ignoring HTML5 errors
$page = new DOMDocument();
libxml_use_internal_errors(true);
$page->loadHTMLFile($url);
libxml_use_internal_errors(false);
$page->normalizeDocument();

# Normalize <link href="..."/>
foreach($page->getElementsByTagName('link') as $link)
    normalizeAttr($link, 'href');
# Normalize <a href="...">...</a>
foreach($page->getElementsByTagName('a') as $anchor)
    normalizeAttr($anchor, 'href');
# Normalize <img src="..."/>
foreach($page->getElementsByTagName('img') as $image)
    normalizeAttr($image, 'src');
# Normalize <script src="..."></script>
foreach($page->getElementsByTagName('script') as $script)
    normalizeAttr($script, 'src');

# Render normalized data
print $page->saveHTML();
于 2017-07-09T19:58:50.693 回答