Приднестровская поддержка XOOPS
Открыть для чтения можно не только локально сохраненный файл, но и файл, находящийся на другом сервере в Интернете. С помощью функций fopen(), file() и file_get_contents() файл можно получить как по протоколу HTTP, так и по протоколу FTP. Для этого достаточно указать соответствующий протокол в URL-адресе, переданном в качестве параметра <Путь к файлу> этим функциям:
http://www.site.ru/file.txt
ftp://www.site.ru/file.txt
Как вам уже известно, в логах сервера отображается программное обеспечение сделавшего запрос клиента. С помощью директивы user_agent в файле php.ini можно задать свое название. Для этого вместо строки
; user_agent="PHP"
нужно написать другую, например:
user_agent="MySpider/1.0"
При обработке больших файлов может потребоваться больше времени, чем задано по умолчанию (30 секунд). Увеличить время работы сценария можно с помощью директивы max_execution_time:
max_execution_time = 120
Кроме того, следует учитывать, что с помощью директивы allow_url_fopen можно запретить открытие внешних файлов. Для получения информации из сети Интернет значение директивы должно быть равно On:
allow_url_fopen = On
Получить документ с помощью функции fopen() можно следующим образом:
$host = 'http://wwwadmin.ru/testrobots.php?var1=10&var2=15';
$content = '';
$header = "User-Agent: MySpider/1.0\r\n";
$header .= "Cookie: test=5\r\n";
$option = array(
'http' => array('method' => 'GET', 'header'=> $header)
);
$context = stream_context_create($option);
@$file = fopen($host, 'r', false, $context);
if ($file) {
while(!feof($file)) {
$content .= fgets($file, 1024);
}
fclose($file);
echo '<b>Содержимое страницы:</b><br><br>';
echo '<pre>' . htmlspecialchars($content) . '</pre>';
}
else {
echo 'Не удалось открыть файл';
}
Если необходимо получить документ в виде массива или строки, то можно воспользоваться функциями file() и file_get_contents():
$host = 'http://wwwtest.ru/testrobots.php?var1=10&var2=15';
$header = "User-Agent: MySpider/1.0\r\n";
$header .= "Cookie: test=5\r\n";
$option = array(
'http' => array('method' => 'GET', 'header'=> $header)
);
$context = stream_context_create($option);
$file1 = implode('', file($host, 0, $context));
if ($file1) {
echo '<b>Содержимое страницы (file()):</b><br><br>';
echo '<pre>' . htmlspecialchars($file1) . '</pre>';
}
$file2 = file_get_contents($host, 0, $context);
if ($file2) {
echo '<b>Содержимое страницы (file_get_contents()):</b><br><br>';
echo '<pre>' . htmlspecialchars($file2) . '</pre>';
}
Функция fsockopen() позволяет получить не только содержимое документа, но и все заголовки ответа сервера. Эта функция очень универсальна и позволяет открыть соединение не только с портом 80, но и с любым другим. Например, можно передать сообщение почтовому серверу на 25-й порт. Функция имеет следующий формат:
fsockopen(<Хост>, <Порт>, [<Номер ошибки>], [<Сообщение об ошибке>], [<Таймаут>]);
Функция устанавливает сетевое соединение и возвращает его дескриптор. Если соединение не установлено, то функция возвращает false. Получить номер и сообщение об ошибке можно с помощью необязательных парамет-
ров <Номер ошибки> и <Сообщение об ошибке>. В необязательном параметре <Таймаут> можно указать максимальное время, в течение которого производится попытка соединения (в секундах). Если параметр не указан, то будет
использовано значение из директивы default_socket_timeout файла php.ini:
default_socket_timeout = 60
После установки соединения необходимо передать заголовки запроса. Между собой заголовки должны разделяться с помощью комбинации символов \r\n. Заголовки должны отделяться от тела запроса с помощью комбинации \r\n\r\n.
Открытым соединением можно манипулировать как обычным файлом с помощью функций fgets(), fwrite(), feof() и др. Закрыть соединение позволяет функция fclose().
Функция stream_set_blocking() позволяет установить режим блокировки соединения. Имеет следующий формат:
stream_set_blocking(<Дескриптор соединения>, <Режим блокировки>);
Если режим равен 1, то функции чтения будут ожидать полного завершения передачи данных. Если указать 0, то блокировка снимается.В качестве примера получим документ методом GET и выведем отдельно заголовки ответа сервера и содержимое документа (листинг 52).
Листинг 52. Чтение документа методом GET
<?php
$page = "/testrobots.php?var1=10&var2=15";
$port = "80";
$host = "wwwadmin.ru";
$header = "GET $page HTTP/1.1\r\n";
$header .= "Host: $host\r\n";
$header .= "User-Agent: MySpider/1.0\r\n";
$header .= "Accept: text/html, text/plain, application/xml\r\n";
$header .= "Accept-Language: ru, ru-RU\r\n";
$header .= "Accept-Charset: windows-1251\r\n";
$header .= "Accept-Encoding: identity\r\n";
$header .= "Connection: close\r\n";
$header .= "Cookie: test=5\r\n";
$header .= "\r\n";
@$fsock = fsockopen($host, $port, $err, $err_text, 30);
if ($fsock) {
stream_set_blocking($fsock, 0);
fwrite($fsock, $header);
$s = 5;
$content = "";
$headers = "";
$buffer = "";
while(!feof($fsock)) {
$buffer = fgets($fsock, 1024);
if ($buffer == "\r\n") { $s = 10; }
if ($s == 5) { $headers .= $buffer; }
else { $content .= $buffer; }
}
fclose($fsock);
}
else {
echo "Произошла ошибка " . $err . ": " . $err_text;
}
echo "<b>Заголовки ответа сервера:</b><br><br>";
echo "<pre>" . htmlspecialchars($headers) . "</pre>";
echo "<br><br><b>Содержимое страницы:</b><br><br>";
echo "<pre>" . htmlspecialchars($content) . "</pre>";
?>
Обратите внимание на строку
$host = "wwwtest.ru";
Мы не указали протокол соединения, так как протокол http:// по умолчанию закреплен за 80-м портом.
Если необходимо получить только заголовки ответа сервера, то вместо метода GET следует указать метод HEAD. Для этого строку
$header = "GET $page HTTP/1.1\r\n";
следует заменить на
$header = "HEAD $page HTTP/1.1\r\n";
Данные можно передать не только методами GET и HEAD, но и методом POST, имитируя таким образом передачу данных формы. Рассмотрим это на примере (листинг 53).
Листинг 53. Имитация передачи данных методом POST
<?php
$page = "/testrobots.php";
$port = "80";
$host = "wwwadmin.ru";
$header = "POST $page HTTP/1.1\r\n";
$header .= "Host: $host\r\n";
$header .= "User-Agent: MySpider/1.0\r\n";
$header .= "Accept: text/html, text/plain, application/xml\r\n";
$header .= "Accept-Language: ru, ru-RU\r\n";
$header .= "Accept-Charset: windows-1251\r\n";
$header .= "Accept-Encoding: identity\r\n";
$header .= "Connection: close\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: 15\r\n";
$header .= "Cookie: test=5\r\n";
$header .= "\r\n";
@$fsock = fsockopen($host, $port, $err, $err_text, 30);
if ($fsock) {
stream_set_blocking($fsock, 0);
fwrite($fsock, $header);
fwrite($fsock, "var1=10&var2=15");
$s = 5;
$content = "";
$headers = "";
$buffer = "";
while(!feof($fsock)) {
$buffer = fgets($fsock, 1024);
if ($buffer == "\r\n") { $s = 10; }
if ($s == 5) { $headers .= $buffer; }
else { $content .= $buffer; }
}
fclose($fsock);
}
else {
echo "Произошла ошибка " . $err . ": " . $err_text;
}
echo "<b>Заголовки ответа сервера:</b><br><br>";
echo "<pre>" . htmlspecialchars($headers) . "</pre>";
echo "<br><br><b>Содержимое страницы:</b><br><br>";
echo "<pre>" . htmlspecialchars($content) . "</pre>";
?>
В этом примере мы заменили метод передачи данных с GET на POST и добавили два заголовка:
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: 15\r\n";
Первый заголовок имитирует передачу данных формы, а второй указывает длину данных, переданных методом POST. Сами данные мы передаем после всех заголовков:
fwrite($fsock, "var1=10&var2=15");
Отправитель | Нити |
---|
6 пользователь(ей) активно (4 пользователь(ей) просматривают Инструкции)
Участников: 0 Гостей: 6 далее... |