Основные приёмы сохранения страницы PHP в файл

Раздел: Работа с файлами -> Сохранение данных

Основные способы сохранения страницы в PHP

Основной способ, обеспечивающий максимальную гибкость и контроль, это использование буферизации вывода в сочетании с функцией записи файла. Буферизация позволяет захватить любой вывод скрипта, включая HTML, JSON, XML, и сохранить его в файл. Рекомендуется использовать этот метод для создания статических копий динамических страниц.


<?php
// Включаем буферизацию
ob_start();

// Здесь генерируется содержимое страницы
echo '<!DOCTYPE html>';
echo '<html><head><title>Пример</title></head><body>';
echo '<p>Это содержимое будет сохранено.</p>';
echo '</body></html>';

// Получаем содержимое буфера и выключаем буферизацию
$pageContent = ob_get_clean();

// Записываем в файл
if (file_put_contents('saved_page.html', $pageContent) !== false) {
    echo 'Страница сохранена успешно.';
} else {
    echo 'Ошибка при записи файла.';
}
?>

сохранить страницу php (сохранение страницы в php)

Типичные ошибки и их решения:
  • Отсутствие прав на запись в директории. Решение: установить правильные разрешения (chmod 755 для папки, 644 для файла).
  • Буферизация не захватывает вывод, если используется output_handler. Решение: отключить или настроить обработчик.
  • Проблемы с кодировкой (например, utf-8 BOM). Решение: явно указывать кодировку в outgoing header или использовать iconv.

Как сохранить удалённую веб-страницу через cURL?

cURL является мощным инструментом для получения содержимого внешних ресурсов. Он поддерживает различные протоколы, таймауты, куки и заголовки.


<?php
$url = 'https://api.example.com/data';
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSL_VERIFYPEER => false, // только для тестирования
    CURLOPT_TIMEOUT => 30,
    CURLOPT_USERAGENT => 'Mozilla/5.0'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
    // обработка ошибки
    $error = curl_error($ch);
    file_put_contents('error_log.txt', $error);
}
curl_close($ch);
if ($httpCode == 200) {
    file_put_contents('external_page.html', $response);
    echo 'Страница сохранена.';
}
?>
Частые проблемы:
  • SSL-сертификат не проверяется. Решение: настроить CA bundle или отключить проверку (небезопасно).
  • Сервер возвращает ошибку 403 или 404. Решение: проверять HTTP-код и логировать.
  • Ограничение памяти для больших страниц. Решение: использовать CURLOPT_FILE для записи напрямую в поток.

Как получить содержимое страницы через file_get_contents с учётом контекста?

Для простых сценариев без авторизации подходит file_get_contents с настройками потока. Требуется включённая директива allow_url_fopen.


<?php
$options = [
    'http' => [
        'header' => "Accept: text/html\r\n" .
                     "Accept-Language: ru-RU\r\n",
        'method' => 'GET'
    ]
];
$context = stream_context_create($options);
$html = @file_get_contents('https://example.com', false, $context);
if ($html === false) {
    // обрабатываем ошибку
    echo 'Не удалось загрузить страницу.';
} else {
    file_put_contents('page_via_fgc.html', $html);
    echo 'Страница сохранена.';
}
?>
Сложности:
  • Отсутствие контроля над таймаутами (по умолчанию default_socket_timeout). Решение: изменить настройки PHP или использовать cURL.
  • Не поддерживает HTTPS, если OpenSSL не настроен. Решение: проверить наличие расширения openssl.
  • Не поддерживает редиректы автоматически (кроме HTTP 301/302). Решение: использовать allow_url_fopen с опцией follow_location (в некоторых версиях).

Как сохранить страницу с базовой HTTP-аутентификацией?

При доступе к защищённым страницам требуется передача логина и пароля. cURL упрощает эту задачу.


<?php
$url = 'https://private.example.com';
$username = 'admin';
$password = 'secret';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
$html = curl_exec($ch);
curl_close($ch);
file_put_contents('protected_page.html', $html);
?>
Потенциальные ошибки:
  • Неверные учётные данные приводят к получению страницы с ошибкой 401. Решение: проверять HTTP-код.
  • Пароль содержит специальные символы. Решение: использовать rawurlencode или передавать через CURLOPT_HTTPHEADER.

Параллельное сохранение множества страниц через curl_multi

Пример

<?php
$urls = [
    'https://example.com/page1',
    'https://example.com/page2',
    'https://example.com/page3'
];
$multi = curl_multi_init();
$handles = [];
foreach ($urls as $i => $url) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HEADER => false,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_TIMEOUT => 10
    ]);
    curl_multi_add_handle($multi, $ch);
    $handles[$i] = $ch;
}
$running = null;
do {
    $status = curl_multi_exec($multi, $running);
    curl_multi_select($multi); // ожидание активности
} while ($running > 0 && $status == CURLM_OK);
foreach ($handles as $i => $ch) {
    $content = curl_multi_getcontent($ch);
    $filename = 'page' . ($i+1) . '.html';
    file_put_contents($filename, $content);
    curl_multi_remove_handle($multi, $ch);
    curl_close($ch);
}
curl_multi_close($multi);
?>
После выполнения скрипта в директории появляются файлы page1.html, page2.html, page3.html, содержащие соответствующие страницы. Время выполнения значительно меньше суммы последовательных запросов.

Очистка HTML от скриптов перед сохранением

Пример

<?php
$html = file_get_contents('https://example.com/dirty');
$doc = new DOMDocument();
@$doc->loadHTML($html);
$scripts = $doc->getElementsByTagName('script');
while ($scripts->length > 0) {
    $scripts->item(0)->parentNode->removeChild($scripts->item(0));
}
$cleanHtml = $doc->saveHTML();
file_put_contents('clean_page.html', $cleanHtml);
?>
Файл clean_page.html содержит HTML без тегов script, что уменьшает риск выполнения нежелательного кода при отображении статической копии.

Сжатие сохранённой страницы в gzip

Пример

<?php
// Создаём буфер и сразу сжимаем
ob_start('ob_gzhandler');
echo file_get_contents('https://example.com/large');
$compressed = ob_get_clean();
file_put_contents('page.gz', $compressed);
// Альтернатива: сохранить обычный HTML, затем сжать через gzencode
$html = file_get_contents('https://example.com/large');
$gzData = gzencode($html, 9);
file_put_contents('page2.gz', $gzData);
?>
Полученные файлы page.gz и page2.gz содержат сжатые версии страницы, что экономит дисковое пространство. Размер может уменьшиться в 5-10 раз.

Сохранение страницы с использованием сессионных cookie (аутентификация)

Пример

<?php
// Вход на сайт через POST, получение cookie
$loginUrl = 'https://example.com/login';
$postData = 'username=user&password=pass';
$ch = curl_init($loginUrl);
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $postData,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_COOKIEJAR => 'cookies.txt',
    CURLOPT_COOKIEFILE => 'cookies.txt'
]);
curl_exec($ch);
curl_close($ch);
// Теперь используем те же cookie для получения защищённой страницы
$ch = curl_init('https://example.com/private');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_COOKIEFILE => 'cookies.txt'
]);
$html = curl_exec($ch);
curl_close($ch);
file_put_contents('private_page.html', $html);
?>
Если аутентификация прошла успешно, файл private_page.html содержит контент, доступный только авторизованным пользователям. Cookie хранятся в файле cookies.txt.

Сохранение страницы в PHP - comments

En
сохранить страницу php (php)