class HTTP {
/*
* в режиме отладки функция не делает редирект, а просто выводит ссылку
*/
function redirect($url, $debug_constant_name = 'DEBUG_MODE') {
$input_url = $url;
// если путь не абсолютный
if (!preg_match("~^(https?|ftp|mailto|ed2k)://~", $url)) {
$server = $_SERVER['HTTP_HOST'];
if (!isset($_SERVER['SERVER_PORT']) ||
in_array($_SERVER['SERVER_PORT'], array(80, 433))) {
$port = '';
} else {
$port = ':'.$_SERVER['SERVER_PORT'];
}
$protocol = 'http';
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
$protocol .= 's';
// генерируем путь
if ($url{0} != '/') {
$path = dirname($_SERVER['PHP_SELF']);
if (strlen($path) <= 1) $path = '/';
else $path .= '/';
$url = $path.$url;
}
$url = $protocol.'://'.$server.$port.$url;
// чистим путь - убираем всякие './' , '../', '//'
$url_parts = parse_url($url);
$paths = array_reverse(explode("/", $url_parts['path']));
$delete_next = 0;
foreach ($paths as $k=>$v) {
if (empty($v) || $v == '.') unset($paths[$k]);
elseif ($v == '..') {
$delete_next++;
unset($paths[$k]);
continue;
} elseif ($delete_next) {
unset($paths[$k]);
$delete_next--;
}
}
$path = '/'.implode('/', array_reverse($paths));
$url = $url_parts['scheme'].'://'.$url_parts['host'];
if (isset($url_parts['port'])) $url .= ':'.$url_parts['port'];
$url .= $path;
if (isset($url_parts['query'])) $url .= '?'.$url_parts['query'];
}
// если была включена буферизация - очищаем буфер
if (!defined($debug_constant_name)) {
for ($i = 0, $level = ob_get_level(); $i < $level; $i++) ob_end_clean();
}
$headers = array();
$mode = php_sapi_name();
// !!! здесь могут быть ошибки в "нестандартных" установках ПХП
if (strpos($mode, 'cgi')) {
$headers[] = 'Status: 307 Temporary redirect';
} else {
$headers[] = 'HTTP/1.1 307 Temporary redirect';
}
$headers[] = "Location: ".$url;
if (!defined($debug_constant_name)) {
foreach($headers as $header)
header($header);
} else {
// debug mode
echo "Input URL: ".htmlspecialchars($input_url).' ';
echo "" ; print_r($headers); echo "";
echo '.$url.'">'.htmlspecialchars($url).' ';
}
}
}
?>
|