Продолжать работу скрипта, даже если подключенный файл не доступен

Sergo_Sev

Творец
Регистрация
14 Июн 2008
Сообщения
578
Реакции
193
Сегодня обнаружил такую пролему - сайт лежит, хотя все в порядке, оказалось, что в одном из файлов идет открытие удаленного файла через fopen, а тот сайт в свою очередь лежит

Как сделать, что бы при запросе файла index.php, генерирующего главную страницу сайта она спокойно открывалась и без задержек, даже если если запрашиваемый удаленный адрес не доступен

Вот такой файл подключен в index.php, а адрес http:// seobudget.ru/downloads/updates.xml полностью недоступен

PHP:
$updates_block = dle_cache( "updates_block", $config['skin'] );
 
if( ! $updates_block ) {
 
    $fd = @fopen("http://seobudget.ru/downloads/updates.xml", "r");
 
    if( $fd ) {
 
    $text="";
    while (!@feof ($fd)) $text .= fgets($fd, 1024);
    @fclose ($fd);
 
 
 
    $pattern = "#timestamp=\"(\d+)\">#i";
    @preg_match_all($pattern, $text, $out);
    $info = array_chunk( $out[1], 3);
 
    // Обновления тИЦ Яндекса
    $cy_up_new = date( 'd.m.Y', $info[0][0]);
    $cy_up_mid = date( 'd.m.Y', $info[0][1]);
    $cy_up_old = date( 'd.m.Y', $info[0][2]);
 
    // Обновления поисковой базы Яндекса
    $cy_base_new = date( 'd.m.Y', $info[1][0]);
    $cy_base_mid = date( 'd.m.Y', $info[1][1]);
    $cy_base_old = date( 'd.m.Y', $info[1][2]);
 
    // Обновление Яндекс.Каталога
    $yaca_up_new = date( 'd.m.Y', $info[2][0]);
    $yaca_up_mid = date( 'd.m.Y', $info[2][1]);
    $yaca_up_old = date( 'd.m.Y', $info[2][2]);
 
 
 
    $tpl->load_template('/pr-cy/updates_block.tpl');
 
    $tpl->set('{cy_new_up}', $cy_up_new);
    $tpl->set('{cy_mid_up}', $cy_up_mid);
    $tpl->set('{cy_old_up}', $cy_up_old);
 
    $tpl->set('{cy_base_new}', $cy_base_new);
    $tpl->set('{cy_base_mid}', $cy_base_mid);
    $tpl->set('{cy_base_old}', $cy_base_old);
 
    $tpl->set('{yaca_up_new}', $yaca_up_new);
    $tpl->set('{aca_up_mid}', $yaca_up_mid);
    $tpl->set('{yaca_up_old}', $yaca_up_old);
 
    $tpl->set( '[if-have-info]', "" );
    $tpl->set( '[/if-have-info]', "" );
    $tpl->compile('updates_block');
    $tpl->clear();
 
    $updates_block = $tpl->result['updates_block'];
    create_cache( "updates_block", $updates_block, $config['skin'] );
 
    }
    else {
        $tpl->load_template('/pr-cy/updates_block.tpl');
          $tpl->set_block( "'\\[if-have-info\\](.*?)\\[/if-have-info\\]'si", "Данные временно не доступны." );
          $tpl->compile('updates_block');
        $tpl->clear();
        $updates_block = $tpl->result['updates_block'];
    }
 
}
 
Я разобью твой вопрос на два:
>> Как сделать, что бы при запросе файла index.php, генерирующего главную страницу сайта она открывалась даже если если запрашиваемый удаленный адрес не доступен.
Она и так должна открываться. Если файл (в твоем случае удаленная URL) недоступен, то php генерирует WARNING (Warning: fopen(Для просмотра ссылки Войди или Зарегистрируйся)....). Возможные причины лежания твоего скрипта - ошибка где-то дальше в ветке else (скорее всего, проверить не могу хз что там за $tpl), заканчивается время выполнения, в системе поставлено очень большое время ожидания открытия, прикручена какая-нить экзотика типа своего обработчика warning-ов.
>> Как сделать, что бы при запросе файла index.php, генерирующего главную страницу сайта она открывалась без задержек даже если если запрашиваемый удаленный адрес не доступен.
Мне такой метод с использованием fopen неизвестен.

Я бы предложил такое решение:

PHP:
function read_url($url, $connect_timeout = 2, $read_timeout = 5) {
    $uri = parse_url($url);
    if(!$uri['host']) $uri = parse_url("http://" . $Url);
    if(!$uri['host']) return false;
    if(!$ip = gethostbyname($uri['host'])) return false;
    if(!$stream = fsockopen($ip, 80, $tmp, $tmp, $connect_timeout)) return false;
    stream_set_timeout($stream, $read_timeout);
    fwrite($stream, "GET $uri[path] HTTP/1.1\r\nHost: $uri[host]\r\nConnection: Close\r\n\r\n");
    $contents = '';
    while (!feof($stream)) {
        $contents .= fread($stream, 8192);
    }
    fclose($stream);
    return $contents;
}
 
.....
 
 
$fd = read_url("http://seobudget.ru/downloads/updates.xml");
 
Скорее всего заканчивается время выполнения, но пользователи вряд ли захотят ждать больше 30 секунд пока страница загрузиться
 
Скорее всего заканчивается время выполнения, но пользователи вряд ли захотят ждать больше 30 секунд пока страница загрузиться

Скорее всего да.

Перестань делать загрузку со внешнего сервера для каждого посещения пользователем index.php и сделай кеширование результатов. Судя по тому что я вижу в кеше гугла, этот файл даже раз в сутки дёргать - слишком часто...
 
Назад
Сверху