Извлечение содержимого URL с помощью метода POST

Задача
Необходимо получить содержимое URL с помощью метода POST, а не метода GET, применяемого обычно. Например, требуется отправить HTML-форму.

Решение
Это делается при помощи расширения cURL с установленным параметром CURLOPT_POST:

$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);
$page = curl_exec($c);
curl_close($c);Если расширение cURL недоступно, то применяется класс HTTP_Request
из PEAR:
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->addPostData('rhino','aunt');
$r->sendRequest();
$page = $r->getResponseBody();

Обсуждение
Посылка запроса с методом POST требует специальной обработки любых аргументов. В запросе GET эти аргументы заключены в строке запроса, но в запросе POST они находятся в теле запроса. Кроме того, запросу необходим заголовок Content-Length, сообщающий серверу ожидаемый размер содержимого в теле запроса.

Из-за обработки аргументов и дополнительных заголовков невозможно посредством функции fopen() построить запрос POST.


Если недоступны ни расширение cUrl, ни класс HTTP_Request, то обратитесь к функции pc_post_request(), показанной в примере 1.1, которая осуществляет соединение с удаленным веб-сервером с помощью функции fsockopen().

Пример 11.1. pc_post_request()
function pc_post_request($host,$url,$content='') {
$timeout = 2;
$a = array();
if (is_array($content)) {
foreach ($content as $k => $v) {
array_push($a,urlencode($k).'='.urlencode($v));
}
}
$content_string = join('&',$a);
$content_length = strlen($content_string);
$request_body = "POST $url HTTP/1.0
Host: $host
Content-type: application/x-www-form-urlencoded
Content-length: $content_length
$content_string";
$sh = fsockopen($host,80,&$errno,&$errstr,$timeout)
or die("can't open socket to $host: $errno $errstr");
fputs($sh,$request_body);
$response = '';
while (! feof($sh)) {
$response .= fread($sh,16384);
}
fclose($sh) or die("Can't close socket handle: $php_errormsg");list($response_headers,$response_body) = explode("\r\n\r\n",$response,2);
$response_header_lines = explode("\r\n",$response_headers);
// первая строка заголовков представляет код ответа HTTP
$http_response_line = array_shift($response_header_lines);
if (preg_match('@^HTTP/[0-9]\.[0-9] ([0-9]{3})@',$http_response_line,
$matches)) {
$response_code = $matches[1];
}
// помещаем оставшиеся части заголовков в массив
$response_header_array = array();
foreach ($response_header_lines as $header_line) {
list($header,$value) = explode(': ',$header_line,2);
$response_header_array[$header] = $value;
}
return array($response_code,$response_header_array,$response_body);
}

Функцию pc_post_request() надо вызывать так:

list($code,$headers,$body) = pc_post_request('www.example.com','/submit.php',
array('monkey' => 'uncle',
'rhino' => 'aunt'));

Получение доступа к URL с помощью метода POST вместо метода GET особенно полезно, если URL очень длинный, более 200 символов или около того.


Спецификация HTTP 1.1 в RFC 2616 не ограничивает максимальную длину URL, поэтому поведение различных веб- и прокси-серверов отличается. Если вы извлекаете содержимое URL с помощью метода GET и получаете неожиданные результаты или результаты с кодом статуса 414 («Request-URI Too Long» (Запрос-URI слишком длинный)), то измените метод запроса на POST.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Анализ файла протокола веб-сервера
Выделение информации на веб-странице
Извлечение ссылок из HTML-файла
Использование шаблонов системы Smarty
Отладка обмена заголовками HTTP

Вернуться в раздел: PHP / 11. Автоматизация работы с Web