Предположим, у меня есть URL-адрес документа, связанного с другим документом (который может быть как абсолютным, так и относительным), и мне нужно, чтобы эта ссылка была абсолютной.
Я сделал простую функцию, обеспечивающую эту функцию для нескольких распространенных случаев:
function absolute_url($url,$parent_url){ $parent_url=parse_url($parent_url); if(strcmp(substr($url,0,7),'http://')==0){ return $url; } elseif(strcmp(substr($url,0,1),'/')==0){ return $parent_url['scheme']."://".$parent_url['host'].$url; } else{ $path=$parent_url['path']; $path=substr($path,0,strrpos($path,'/')); return $parent_url['scheme']."://".$parent_url['host']."$path/".$url; } } $parent_url='http://example.com/path/to/file/name.php?abc=abc'; echo absolute_url('name2.php',$parent_url)."\n"; // output http://example.com/path/to/file/name2.php echo absolute_url('/name2.php',$parent_url)."\n"; // output http://example.com/name2.php echo absolute_url('http://name2.php',$parent_url)."\n"; // output http://name2.php
Код работает нормально, но может быть больше таких случаев, как ../../path/to/file.php
которые не будут работать.
Так есть ли какие-либо стандартные классы или функции, делающие эту вещь лучше (более универсальной), что моя функция?
Я попробовал Google и проверял аналогичные вопросы ( один и два ), но это похоже на решение, связанное с сервером, и это не то, что я ищу.
$uri = ".."; $path = realpath($uri); $root = realpath($_SERVER["DOCUMENT_ROOT"]); if($path){ $path = str_replace($root, "", $path); $path = $_SERVER["SERVER_NAME"] . $path; $protocol = "http"; if(isset($_SERVER["HTTPS"])){ $protocol .= "s"; } $path = "{$protocol}://$path"; $path = str_replace("\\", "/", $path); } var_dump($path);
Вероятно, лучше или быстрее, но я просто сбил это …
Эта функция будет разрешать относительные URL-адреса для заданного текущего URL-адреса страницы в $pgurl
без регулярного выражения . Он успешно решает:
/home.php?example
типы,
такие же типы nextpage.php
,
../...../.../parentdir
,
полные URL-адреса http://example.net
,
и сокращенные URL-адреса //example.net
//Current base URL (you can dynamically retrieve from $_SERVER) $pgurl = 'http://example.com/scripts/php/absurl.php'; function absurl($url) { global $pgurl; if(strpos($url,'://')) return $url; //already absolute if(substr($url,0,2)=='//') return 'http:'.$url; //shorthand scheme if($url[0]=='/') return parse_url($pgurl,PHP_URL_SCHEME).'://'.parse_url($pgurl,PHP_URL_HOST).$url; //just add domain if(strpos($pgurl,'/',9)===false) $pgurl .= '/'; //add slash to domain if needed return substr($pgurl,0,strrpos($pgurl,'/')+1).$url; //for relative links, gets current directory and appends new filename } function nodots($path) { //Resolve dot dot slashes, no regex! $arr1 = explode('/',$path); $arr2 = array(); foreach($arr1 as $seg) { switch($seg) { case '.': break; case '..': array_pop($arr2); break; case '...': array_pop($arr2); array_pop($arr2); break; case '....': array_pop($arr2); array_pop($arr2); array_pop($arr2); break; case '.....': array_pop($arr2); array_pop($arr2); array_pop($arr2); array_pop($arr2); break; default: $arr2[] = $seg; } } return implode('/',$arr2); }
Пример использования:
echo nodots(absurl('../index.html'));
nodots()
необходимо вызвать после преобразования URL в абсолютный.
Функция точек является излишней, но читается, быстро, не использует регулярные выражения и будет разрешать 99% типичных URL-адресов (если вы хотите быть на 100% уверенным, просто расширяйте блок переключателей, чтобы поддерживать 6+ точек, хотя Я никогда не видел столько точек в URL-адресе).
Надеюсь это поможет,