Консультация № 173235
13.10.2009, 10:57
25.00 руб.
0 4 2
Уважаемые эксперты,

есть ли способ задать следующий сценарий на php: на страничке имеется ссылка на ресурс, который из-за технических неполадок не всегда доступен, но отслеживать это не всегда получается, соответственно, хотелось бы, чтобы сценарий при клике на ссылку проверял, работает ли ресурс в данный момент, а если не работает, то чтобы направлял на зеркало.
Т.е.: если http://www.genling.nw.ru открывается, то пусть пользователь идёт туда, а если не открывается, то пусть идёт на http://www.genlingnw.ru

Заранее спасибо.

Обсуждение

Неизвестный
13.10.2009, 11:27
общий
это ответ
Здравствуйте, Anjali.

Это можно реализовать через использование промежуточного скрипта который будет проверять доступность удаленного ресурса и решать куда в действительности производить перенаправление. При этом, правда, придется пожертвовать "прямой" ссылкой на удаленный ресурс либо использовать JavaScript.

При этом, по соображениям безопасности, лучше не передавать полный url в качестве параметра к скрипту, а вместо этого хранить реальные url'и например в базе данных и передавать скрипту редиректа только id url'я. В противном случае возможен сценарий использования вашего скрипта для нечестных целей, например для фишинга.

Пример того как может выглядеть скрипт перенаправления - в приложении.

Приложение:
<?php
// Получаем URL ID
$id = (isset($_GET['id']))?$_GET['id']:null;

// .... Здесь располагается код получения списка URLs из базы данных в переменную $urls ....

// Проверяем доступность каждого url'я
foreach($urls as $url)
{
$p = parse_url($url);
if (!isset($p['host']))
continue;
// Пробуем открыть socket соединение с удаленным сервером
$fp = fsockopen($p['host'],80,$errno,$errstr,5);
if (!is_resource($fp))
// Соединение установить не удалось
continue;
// Следующий шаг даст больше уверенности что сайт работает, но потребует больше времени на выполнение
$http = 'HEAD '.((isset($p['path']))?$p['path']:'/').' HTTP/1.1'."\r\n";
$http .= 'Host: '.$p['host']."\r\n";
$http .= 'Connection: close'."\r\n\r\n";
fwrite($fp,$http);
$response = '';
while (!feof($fp))
$response .= fgets($fp, 4096);
fclose($fp);
// Проверяем код ответа
if (!preg_match('/^HTTP\/\d+\.\d+\s+(\d+)/i',$response,$t))
continue;
if ($t[1]>=400)
// Код ответа сигнализирует об ошибке
continue;
// Все в порядке, осуществляем редирект на выбранный url
header('Location: '.$url);
exit();
};
// Ни одного подходящего url'я не найдено...
?>
5
Неизвестный
13.10.2009, 11:51
общий
это ответ
Здравствуйте, Anjali.
вот функция, проверяющая ссылку:
<?php
function check_url($url) {
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_HEADER, 1); // get the header
curl_setopt($c, CURLOPT_NOBODY, 1); // and *only* get the header
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); // get the response as a string from curl_exec(), rather than echoing it
curl_setopt($c, CURLOPT_FRESH_CONNECT, 1); // don't use a cached version of the url
if (!curl_exec($c)) { return false; }

$httpcode = curl_getinfo($c, CURLINFO_HTTP_CODE);
return ($httpcode < 400);
}
?>

Вы должны будете вместо ссылки на ресурс указывать ссылку на свой скрипт, который, проверив нужную ссылку, перенаправляет клиента на неё или берёт другую ссылку.

Пример кода в приложении

Приложение:
<?php
function check_url($url) {
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_HEADER, 1); // get the header
curl_setopt($c, CURLOPT_NOBODY, 1); // and *only* get the header
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); // get the response as a string from curl_exec(), rather than echoing it
curl_setopt($c, CURLOPT_FRESH_CONNECT, 1); // don't use a cached version of the url
if (!curl_exec($c)) { return false; }

$httpcode = curl_getinfo($c, CURLINFO_HTTP_CODE);
return ($httpcode < 400);
} ;

$urls = array ( "http://www.genling.nw.ru" , "http://www.genlingnw.ru" );

foreach ($urls AS $url) {

if (check_url($url)) {
header("Location: $url");
exit;
};

};

?>
5
Такое решение показалось наиболее оптимальным и более понятным.
Неизвестный
13.10.2009, 12:11
общий
Спасибо )) надеюсь, cURL у Вас на хостинге установлен... Иначе придётся переписАть функцию проверки, например, с помощью сокетов, как в первом ответе
Неизвестный
13.10.2009, 12:23
общий
Проверила - работает! Так что спасибо ещё раз
Форма ответа