Абсолютный URL на PHP
К моему большому удивлению, в PHP нет готовой функции для построения абсолютного URL по относительному и базовому. Пришлось писать ее самому. И вот что получилось:
function abs_url($rel,$base) {
$relp = parse_url($rel); // parts of relative url
$basep = parse_url($base); // parts of base url
$result = '';
$prev_changed = false; // indicator whether the preious part of url was changed, if true, no latter parts of base will be used
if (empty($basep['scheme'])) $basep['scheme']='http';
$scheme = !empty($relp['scheme']) ? $relp['scheme'] : $basep['scheme'];
if ($scheme) $result.=$scheme.':';
if (!empty($relp['host'])) {
$host = $relp['host'];
$prev_changed = true;
}
else $host=$basep['host'];
if ($host) $result.='//';
if (!empty($relp['user']) || !empty($basep['user'])) {
$user = !empty($relp['user']) ? $relp['user'] : $basep['user'];
$password = !empty($relp['password']) ? $relp['password'] : $basep['password'];
$result.=urlencode($user);
if ($password) $result.=':'.urlencode($password);
$result.='@';
}
$result.=$host;
if (!empty($relp['port']) || !empty($basep['port'])) {
$port = !empty($relp['port']) ? $relp['port'] : $basep['port'];
$result.=':'.$port;
}
if (!$prev_changed) {
if (empty($basep['path'])) $basep['path']='/';
if (empty($relp['path'])) $path=$basep['path'];
elseif ($relp['path'][0]==='/') {
$path=$relp['path'];
$prev_changed = true;
}
else {
$path=dirname($basep['path'].'.');
if ($path!=='/' && $path!=='\\') $path.='/';
$path.=$relp['path'];
$prev_changed = true;
}
$result.=$path;
}
elseif (!empty($relp['path'])) $result.=$relp['path'];
if (!empty($relp['query'])) {
$result.='?'.$relp['query'];
$prev_changed = true;
}
elseif (!$prev_changed && !empty($basep['query'])) $result.='?'.$basep['query'];
if (!empty($relp['fragment'])) $result.='#'.$relp['fragment'];
elseif (!$prev_changed && !empty($basep['fragment'])) $result.='#'.$basep['fragment'];
return $result;
}
Использование: $url = absolute_url($relative_url,$base_url);
, где $relative_url - относительный URL, $base_url - базовый, относительно которого происходит дополнение.
Также этот код, но оформленный в виде класса, я выложил на GitHub.