Необходимо проанализировать HTTP-запрос броузера к серверу и соответствующий HTTP-ответ. Например, сервер не выдает ожидаемого ответа на определенный запрос, поэтому требуется точно определить, какие компоненты запрашивались.
Если запросы простые, надо соединиться с веб-сервером c помощью программы telnet и ввести с клавиатуры следующие заголовки запроса:
% telnet www.example.com 80
Trying 10.1.1.1...
Connected to www.example.com.
Escape character is '^]'.
GET / HTTP/1.0
Host: www.example.com
HTTP/1.1 200 OK
Date: Sat, 17 Aug 2002 06:10:19 GMT
Server: Apache/1.3.26 (UNIX) PHP/4.2.2 mod_ssl/2.8.9 OpenSSL/0.9.6d
X Powered By: PHP/4.2.2
Connection: close
Content Type: text/html
// ... основная часть страницы ...
Когда вы печатаете от руки заголовки запроса, веб-сервер не знает, что
это именно вы печатаете, а не броузер представляет запрос. Однако некоторые веб-серверы определенное время ожидают запроса, поэтому
иногда удобнее заблаговременно набрать запрос, а затем вставить его в
окно программы telnet. Первая строка запроса содержит метод запроса
(GET), пробел и путь к требуемому файлу (/), а затем пробел и используемый протокол (HTTP/1.0). Следующая строка, заголовок Host, сообщает серверу, какой виртуальный сервер использовать, если несколько
серверов используют один и тот же IP-адрес. Пустая строка говорит
серверу, что запрос завершен; тогда он выдает свой ответ: сначала заголовки, потом пустую строку, а затем основное содержание ответа.
Вставка текста в окно программы telnet может быть утомительным занятием, а еще труднее таким образом делать запросы методом POST.
При посылке запроса с использованием класса HTTP_Request можно получить заголовки и тело ответа с помощью методов getResponseHeader() и getResponseBody():
require 'HTTP/Request.php';
$r = new HTTP_Request('http://www.example.com/submit.php');
$r->setMethod(HTTP_REQUEST_METHOD_POST);
$r->addPostData('monkey','uncle');
$r->sendRequest();
$response_headers = $r->getResponseHeader();
$response_body = $r->getResponseBody();
Чтобы получить определенный заголовок ответа, передайте имя заголовка функции getResponseHeader(). Без аргумента метод getResponseHeader() возвращает массив, содержащий все заголовки ответа. Класс HTTP_Request не сохраняет выходящие запросы в переменной, но его можно реконструировать с помощью вызова частного метода _buildRequest():
require 'HTTP/Request.php';
$r = new HTTP_Request('http://www.example.com/submit.php');
$r->setMethod(HTTP_REQUEST_METHOD_POST);
$r->addPostData('monkey','uncle');
print $r->_buildRequest();
Напечатанный запрос выглядит так:
POST /submit.php HTTP/1.1
User-Agent: PEAR HTTP_Request class ( http://pear.php.net/ )
Content-Type: application/x-www-form-urlencoded
Connection: close
Host: www.example.com
Content-Length: 12
monkey=uncle
При использовании расширения c URL для включения заголовков ответа в вывод функции curl_exec() установите параметр CURLOPT_HEADER:
$c = curl_init('http://www.example.com/submit.php');
curl_setopt($c, CURLOPT_HEADER, 1);
curl_setopt($c, CURLOPT_POST, 1);
curl_setopt($c, CURLOPT_POSTFIELDS, 'monkey=uncle&rhino=aunt');
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
$response_headers_and_page = curl_exec($c);
curl_close($c);
Чтобы записать заголовки ответа в файл на диске, откройте дескриптор файла с помощью функции fopen() и установите для этого дескриптора файла параметр CURLOPT_WRITEHEADER:
$fh = fopen('/tmp/curl-response-headers.txt','w') or die($php_errormsg);
$c = curl_init('http://www.example.com/submit.php');
curl_setopt($c, CURLOPT_POST, 1);
curl_setopt($c, CURLOPT_POSTFIELDS, 'monkey=uncle&rhino=aunt');
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_WRITEHEADER, $fh);
$page = curl_exec($c);
curl_close($c);
fclose($fh) or die($php_errormsg);
Параметр CURLOPT_VERBOSE модуля c URL заставляет функции curl_exec() и curl_close() выводить отладочную информацию в поток стандартных ошибок, включая содержимое запроса:
$c = curl_init('http://www.example.com/submit.php');
curl_setopt($c, CURLOPT_VERBOSE, 1);
curl_setopt($c, CURLOPT_POST, 1);
curl_setopt($c, CURLOPT_POSTFIELDS, 'monkey=uncle&rhino=aunt');
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
$page = curl_exec($c);
curl_close($c);
В результате будет напечатано:
* Connected to www.example.com (10.1.1.1)
> POST /submit.php HTTP/1.1
Host: www.example.com
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Content-Length: 23
Content-Type: application/x-www-form urlencoded
monkey=uncle&rhino=aunt* Connection #0 left intact
* Closing connection #0
Поскольку расширение c URL выводит отладочную информацию в поток стандартных ошибок, а не в стандартный поток вывода, он не может быть захвачен буфером вывода, подобно тому как в рецепте (Регистрация отладочной информации и ошибок) это делается с помощью функции print_r(). Однако чтобы направить отладочную информацию в файл, можно открыть дескриптор файла на запись и установить для этого дескриптора параметр CURLOUT_STDERR:
$fh = fopen('/tmp/curl.out','w') or die($php_errormsg);
$c = curl_init('http://www.example.com/submit.php');
curl_setopt($c, CURLOPT_VERBOSE, 1);
curl_setopt($c, CURLOPT_POST, 1);
curl_setopt($c, CURLOPT_POSTFIELDS, 'monkey=uncle&rhino=aunt');
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_STDERR, $fh);
$page = curl_exec($c);
curl_close($c);
fclose($fh) or die($php_errormsg);