HTTP и PHP
Довольно часто необходимо решать задачи, так или иначе связанные с отправкой запроса на удаленный сервер и получением данных
с него средствами PHP.
Так, например, многие партнерские программы предоставляют партнерские магазины, и дают свою базу, к примеру, в формате
XML.
Обычно в этой базе содержиться наименование товаров, их описание, цена и пр., причем эти данные постоянно обновляються...
Как быть? Каждый день скачивать базу в формате XML к себе на компьютер, а потом загружать на сервер, и там разбирать?
Ан нет. В этом нам поможет наш старый добрый PHP. Дело в том, что в языке программирования PHP предусмотрены функции,
которые позволяют нам открывать сокеты, соединяться с удаленным сервером, и вести себя как обычный броузер,
т.е. посылать HTTP заголовки.. подставлять HTTP REFERER, USER-AGENT... Все это можно в PHP
Пробежимся немного по HTTP заголовкам.
Немного об HTTP заголовках
Когда наш броузер, к примеру, Internet Explorer, хочет получить содержимое какой-нибудь странички, он посылает серверу
запрос, в котором он указывает, что он хочет получить. Есть три типа HTTP запросов: GET, HEAD и POST.
Синтаксис HTTP заголовков - первой строчкой и первым словом в страничке идет Header - заголовок, потом идут
две пустые строки, и далее - сам документ, каким мы можем просмотреть его в Блокноте например.
Протокол HTTP: GET запрос
GET запрос - означает "получить", т.е. получить содержимое какого-либо документа.
Когда наш Internet Explorer хочет получить содержимое странички http://inetprog.info/index.html, то он отправляет GET запрос,
в котором указывает, что он хочет получить, откуда пользователь узнал об этой страничке(HTTP REFERER), кто посылает запрос(USER-AGENT).
Пример GET запроса:
GET /index.html HTTP/1.0
Host: inetprog.info
Referer: http://inetprog.info
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Connection: close
Как видно из данного примера, броузер разбирает URL на "составляющие", а именно путь к файлу(path) и имя сервера,
к которому он обращаеться(Host), т.е. получаеться так:
"Я User-Agent пришел по рекомендации сервера Referer и хочу получить файл path с сервера host".
Таким образом броузер указывает серверу всю информацию, которую он хочет получить.
Протокол HTTP: HEAD запрос
Head запрос - это можно сравнить с "пингованием", т.е. посылкой пакета и, если сервер ответит, т.е. пошлет другой
пакет, то сервер доступен.
HEAD запрос посылаеться с целью проверить доступность сервера в основном.
Пример HEAD запроса
HEAD /index.html HTTP/1.0
Host: inetprog.info
Как видно из примера, все аналогично HTTP GET запросу, только в GET запросе броузер получает ответ от сервера и содержимое документа,
а в HTTP HEAD запросе только ответ сервера.
Протокол HTTP: POST запрос
HTTP POST запрос несколько интереснее. Он позволяет передать серверу данные методом POST, как, например, когда мы заполняем какую-нибудь форму,
и отправляем данные на сервер.
Синтаксис аналогичен синтаксису GET и HEAD заголовков, но от запроса GET он отличаеться тем, что вместо содержимого документа
подаються параметры и значения, т.е. например:
POST /index.php HTTP/1.0
Referer: http://inetprog.info
Content-Type: application/x-www-form-urlencoded
Content-Length: 15501
Host: inetprog.info
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
parametr=value¶metr2=value2
В HTTP POST запросе необходимо указывать длину передаваемых данных (Content-Length), и тип передаваемых данных
(Content-Type).
Ну все, с заголовками вроде разобрались немножко. Теперь о HTTP и PHP поговорим.
HTTP и PHP
Итак, теперь мы знаем, что такое HTTP заголовки (будем их дальше
называть хэдерами). Теперь посмотрим, как на языке PHP получить данные с сервера, также, "пропингуем" какой-нибудь
сервер и пошлем данные серверу методом POST с помощью языка PHP.
Итак, для начала нам необходимо открыть сокет, потом отправить данные серверу, потом получить данные от сервера.
Все просто. Поехали
Сокеты в PHP
В PHP сокеты открываються функцией fsockopen, а чтение и запись данных с сокета происходит аналогично
функциям работы с файлами - fwrite, fread, fputs,fgets, а закрытие сокета в PHP осуществляеться функцией fclose.
Чтобы послать HTTP запрос на PHP, необходимо открыть сокет, записать данные, дождаться ответа сервера и получить данные с сервера( "прочитать" сокет):
<?php
$url="http://inetprog.info/index.html";
//Обрабатываем("парсим") URL
$url=parse_url($url);
$host=$url['host'];
$page="";
//Открываем сокет
$socket=fsockopen($host,80,$errno,$errstr,60) or die("Can't open socket");
//Передаем данные серверу
fputs($socket, "GET $url['path'] HTTP/1.0\r\n");
fputs($socket, "Referer: http://inetprog.info\r\n");
fputs($socket, "Host: $url['host']\r\n");
fputs($socket, "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
\r\n\r\n");
//Читаем данные с сервера
while(!feof($socket))
{
$page .= fgets($socket);
}
fclose($socket);
//Выводим страницу
print $page;
?>
Вот, все элементарно и просто. HEAD запрос аналогично будет реализован.
Для HTTP POST запроса все аналогично, только необходимо указывать длину передаваемых данных, и тип передаваемых данных, без них сервер выдаст ошибку и запрос не будет обработан.
Вот что еще необходимо добавлять при HTTP POST запросе:
...
fputs($socket,"Content-Type: application/x-www-form-urlencoded\r\n");
fputs($socket,"Content-Length: ".strlen($postdata)."\r\n");
...
Где $postdata - передаваемые данные в виде параметр=значение&параметр1=значение1&...&параметрN=значениеN&...
Вот и все :)
Как время/новые вопросы появяться, еще чего нибудь напишу.
Удачи!
|