Бывают случаи, когда между различными web-сервисами необходимо организовать передачу данных методом POST. Например, один из SMS-агрегаторов, с которым мне довелось поработать, выдавал мне XML-данные через POST. Однако эти данные, к моему удивлению не содержались в массиве $_POST. Поискав некоторое время информацию я узнал каким образом можно получать и отправлять так называемые сырые post-данные, которые не связаны с какими-либо переменными. В этой статье я собрал информацию, которая, я надеюсь, поможет вам при необходимости реализовать такой обмен данными.
Как прочитать скриптом данные, посланные методом POST напрямую?

  1. Размер блока переданных данных содержится в переменной окружения CONTENT_LENGTH и читается из $_ENV["CONTENT_LENGTH"] или getenv(”CONTENT_LENGTH”)
  2. Если PHP установлен как CGI или ваша программа работает из командной строки (в консольном режиме), то данные можно читать из стандартного потока ввода stdin, как из обычного файла.
    Для этого достаточно открыть этот поток как файл:

    $stdin = fopen("php://stdin", "r");
  3. Если PHP используется как модуль Apache, то данные можно получить из глобальной переменной $HTTP_RAW_POST_DATA (она же $GLOBALS['HTTP_RAW_POST_DATA']). Для этого необходимо в файле php.ini раскомментировать (добавить) следующую строчку:
    always_populate_raw_post_data = On

    или добавить в файл .htaccess:

    php_flag always_populate_raw_post_data On

Теперь я хочу привести код отправки данных. Конечно можно это реализовать на сокетах, но я думаю более удобно это делать с помощью curl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$request = '<? xml version="1.0" encoding="utf-8" ?>' .
	'<Countries>' .
		'<country>Russia</country>' .
		'<country>USA</country>' .
		'<country>Ukraine</country>' .
		'<country>Germany</country>' .
	'</Countries>';
 
// Create Headers
$header[] = "Host: mydomain.test";
$header[] = "Content-type: text/xml; charset:utf-8";
$header[] = "Content-length: ".strlen($request);
 
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://mydomain.test/archive/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 ); // return into a variable
curl_setopt($ch, CURLOPT_HTTPHEADER, $header ); // headers from above
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request); 
 
$result = curl_exec( $ch ); // runs the post
curl_close($ch);
echo $result; // echo reply response

А этот код скрипта, который принимает данные (при условии что php используется как модуль Apache):

1
2
3
4
5
6
7
$rawPostData = $GLOBALS['HTTP_RAW_POST_DATA'];
$xml = new SimpleXMLElement($rawPostData);
foreach ($xml as $key => $value) {
	$$key = $value;
	echo '$key = '.$key;
	echo ', $value = '.$value.'<br/>';
}

Вот и вся хитрость! Обязательно напишите, если были какие-то неточности. Пишите как вы решали данную задачу, если она решалась по другому. Мне и другим читателям будет интересно.

Tags: ,

4 Responses to “Передача и получение данных методом POST в PHP”

  1.  Степыч Says:

    Таким же образом можно реализовать выгрузку из 1С

  2.  Fighter Says:

    Спасибо!
    Вы мой спаситель

  3.  Stari40k Says:

    Спасибо. То что искал.

  4.  Stari40k Says:

    Правда в принимающем скрипте удобней сделать вот так.

    $xml = simplexml_load_string($rawPostData);
    $json = json_encode($xml);
    $array = json_decode($json,TRUE);

    echo ‘

    ';
    print_r($array);
    echo '

    ‘;