PHP实现html中url补全函数
应用场景
最近在开发一个安卓客户端,查看文章的内容来自于带有html标签的文章内容字段。安卓的webView能像浏览器一样正确展示这些html内容,但是有一点让人很头疼,图片不能正常显示,因为我的图片路径都是用的相对路径,不带网站域名的,webView当然不能显示了。
于是想在返回客户端的请求之前,在服务端用php代码将这些只有相对路径的URL补全成带域名的形式。可惜自己的正则表达式没学好,根本写不出来。
在网上找了好久,终于找到一个非常好用的。
这个函数不仅仅是补全图片的src url 还能补全超链接等所有的url。
本功能函数进行对代码进行格式化,把所有的超链接都格式化一遍。
路径知识普及
相对路径:“../” “./” 或者前面什么都不加
绝对根路径:/path/xxx.html
绝对全路径:http://www.xxx.com/path/xxx.html
使用实例:
<?php
$surl="http://www.jcodecraeer.com/";
$gethtm = '<a href="/">首页</a><a href="/androiddev/">安卓开发</a>';
echo formaturl($gethtm,$surl);
?>
其中$surl
是你要补全的域名,$gethtm
是要被补全的html字符串,formaturl
函数执行之后$gethtm
字符串中没有域名的url都将被补全。比如此例中href="/androiddev/"
这个/androiddev/
相对url就会被补全成http://www.jcodecraeer.com/`androiddev/`
`` `formaturl`函数代码如下: ``
<?php
function formaturl($l1, $l2) {
if (preg_match_all ( "/(<img\[^>\]+src=\\"(\[^\\"\]+)\\"\[^>\]*>)|(<a\[^>\]+href=\\"(\[^\\"\]+)\\"\[^>\]*>)|(<img\[^>\]+src='(\[^'\]+)'\[^>\]*>)|(<a\[^>\]+href='(\[^'\]+)'\[^>\]*>)/i", $l1, $regs )) {
foreach ( $regs \[0\] as $num => $url ) {
$l1 = str_replace ( $url, lIIIIl ( $url, $l2 ), $l1 );
}
}
return $l1;
}
function lIIIIl($l1, $l2) {
if (preg_match ( "/(.*)(href|src)\\=(.+?)( |\\/\\>|\\>).*/i", $l1, $regs )) {
$I2 = $regs \[3\];
}
if (strlen ( $I2 ) > 0) {
$I1 = str_replace ( chr ( 34 ), "", $I2 );
$I1 = str_replace ( chr ( 39 ), "", $I1 );
} else {
return $l1;
}
$url_parsed = parse_url ( $l2 );
$scheme = $url_parsed \["scheme"\];
if ($scheme != "") {
$scheme = $scheme . "://";
}
$host = $url_parsed \["host"\];
$l3 = $scheme . $host;
if (strlen ( $l3 ) == 0) {
return $l1;
}
$path = dirname ( $url_parsed \["path"\] );
if ($path \[0\] == "\\\\") {
$path = "";
}
$pos = strpos ( $I1, "#" );
if ($pos > 0)
$I1 = substr ( $I1, 0, $pos );
//判断类型
if (preg_match ( "/^(http|https|ftp):(\\/\\/|\\\\\\\\)((\[\\w\\/\\\\\\+\-~\`@:%\])+\\.)+(\[\\w\\/\\\\\\.\\=\\?\\+\-~\`@\\':!%#\]|(&)|&)+/i", $I1 )) {
return $l1;
} //http开头的url类型要跳过
elseif ($I1 \[0\] == "/") {
$I1 = $l3 . $I1;
} //绝对路径
elseif (substr ( $I1, 0, 3 ) == "../") { //相对路径
while ( substr ( $I1, 0, 3 ) == "../" ) {
$I1 = substr ( $I1, strlen ( $I1 ) - (strlen ( $I1 ) - 3), strlen ( $I1 ) - 3 );
if (strlen ( $path ) > 0) {
$path = dirname ( $path );
}
}
$I1 = $l3 . $path . "/" . $I1;
} elseif (substr ( $I1, 0, 2 ) == "./") {
$I1 = $l3 . $path . substr ( $I1, strlen ( $I1 ) - (strlen ( $I1 ) - 1), strlen ( $I1 ) - 1 );
} elseif (strtolower ( substr ( $I1, 0, 7 ) ) == "mailto:" || strtolower ( substr ( $I1, 0, 11 ) ) == "javascript:") {
return $l1;
} else {
$I1 = $l3 . $path . "/" . $I1;
}
return str_replace ( $I2, "\\"$I1\\"", $l1 );
}
?>
` `