Skip to content

Instantly share code, notes, and snippets.

@jerrybendy
Last active July 6, 2018 10:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jerrybendy/dc495f16c5a8da11653e7ecca41ec133 to your computer and use it in GitHub Desktop.
Save jerrybendy/dc495f16c5a8da11653e7ecca41ec133 to your computer and use it in GitHub Desktop.
PHP转换网址相对路径到绝对路径的一种方法 https://icewing.cc/php-conv-addr-re-ab-2.html
/**
* 把从HTML源码中获取的相对路径转换成绝对路径
* @param string $url HTML中获取的网址
* @param string $URI 用来参考判断的原始地址
* @return 返回修改过的网址,如果网址有误则返回FALSE
*/
function filter_relative_url($url, $URI){
//STEP1: 先去判断URL中是否包含协议,如果包含说明是绝对地址则可以原样返回
if(strpos($url, '://') !== FALSE){
return $url;
}
//STEP2: 解析传入的URI
$URI_part = parse_url($URI);
if($URI_part == FALSE)
return FALSE;
$URI_root = $URI_part['scheme'] . '://' . $URI_part['host'] . (isset($URI_part['port']) ? ':' . $URI_part['port'] : '');
//STEP3: 如果URL以左斜线开头,表示位于根目录
if(strpos($url, '/') === 0){
return $URI_root . $url;
}
//STEP4: 不位于根目录,也不是绝对路径,考虑如果不包含'./'的话,需要把相对地址接在原URL的目录名上
$URI_dir = (isset($URI_part['path']) && $URI_part['path']) ? '/' . ltrim(dirname($URI_part['path']), '/') : '';
if(strpos($url, './') === FALSE){
if($URI_dir != ''){
return $URI_root . $URI_dir . '/' . $url;
} else {
return $URI_root . '/' . $url;
}
}
//STEP5: 如果相对路径中包含'../'或'./'表示的目录,需要对路径进行解析并递归
//STEP5.1: 把路径中所有的'./'改为'/','//'改为'/'
$url = preg_replace('/[^\.]\.\/|\/\//', '/', $url);
if(strpos($url, './') === 0)
$url = substr($url, 2);
//STEP5.2: 使用'/'分割URL字符串以获取目录的每一部分进行判断
$URI_full_dir = ltrim($URI_dir . '/' . $url, '/');
$URL_arr = explode('/', $URI_full_dir);
if($URL_arr[0] == '..')
return FALSE;
//因为数组的第一个元素不可能为'..',所以这里从第二个元素可以循环
$dst_arr = $URL_arr; //拷贝一个副本,用于最后组合URL
for($i = 1; $i < count($URL_arr); $i ++){
if($URL_arr[$i] == '..'){
$j = 1;
while(TRUE){
if(isset($dst_arr[$i - $j]) && $dst_arr[$i - $j] != FALSE){
$dst_arr[$i - $j] = FALSE;
$dst_arr[$i] = FALSE;
break;
} else {
$j ++;
}
}
}
}
// 组合最后的URL并返回
$dst_str = $URI_root;
foreach($dst_arr as $val){
if($val != FALSE)
$dst_str .= '/' . $val;
}
return $dst_str;
}
@ieliwb
Copy link

ieliwb commented Jul 6, 2018

http://www.cocoachina.com/ios/20111128/3614.html

../../../uploads/allimg/111128/3866_111128094800_1.png

这个网页补齐死循环 cpu100%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment