Основные приёмы сохранения страницы 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.