При интеграции 1С с веб-сервисами на базе PHP разработчики часто сталкиваются с ситуацией, когда отправленные данные из структуры или соответствия 1С не считываются на стороне сервера. В массиве $_POST ключи оказываются пустыми или вовсе отсутствуют, а обращение к полям вроде $_POST['name'] возвращает пустую строку.
В этой статье мы разберем причины возникновения этой проблемы и рассмотрим два правильных способа передачи и обработки JSON-данных между 1С и PHP.
Проанализируем базовые ошибки, которые приводят к невозможности распарсить запрос:
$_POST: PHP автоматически формирует суперглобальный массив $_POST только на верхнем уровне параметров запроса. Если вы передаете строку вида user={"name":"Ivan"}, то в $_POST['user'] попадет вся сырая JSON-строка. PHP не декодирует вложенные объекты автоматически, поэтому $_POST['name'] будет неопределен.application/x-www-form-urlencoded, всё тело запроса должно соответствовать этому формату. Символы, используемые в JSON (двойные кавычки, фигурные скобки, пробелы и переносы строк), ломают структуру POST-запроса, если их предварительно не заэкранировать.ЗаписьJSON могут вставлять автопереносы строк. Неэкранированный символ перевода строки (\r\n) обрывает чтение параметров на веб-сервере.Наиболее современным и стандартным способом передачи данных для REST API является отправка чистого JSON в теле HTTP-запроса без лишних POST-оберток. В этом случае PHP считывает входной поток напрямую через php://input.
Рассмотрим реализацию этого способа в 1С:
&НаСервере
Функция ОтправитьJSONНаСервер()
Сервер = "192.168.0.68";
Ресурс = "/123.php";
HTTP = Новый HTTPСоединение(Сервер);
// Подготовка данных
Данные = Новый Структура;
Данные.Вставить("name", "Ivan");
// Формирование JSON без переносов строк
ПараметрыJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку(ПараметрыJSON);
ЗаписатьJSON(ЗаписьJSON, Данные);
ТекстJSON = ЗаписьJSON.Закрыть();
// Настройка HTTP-запроса
Запрос = Новый HTTPЗапрос(Ресурс);
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Запрос.УстановитьТелоИзСтроки(ТекстJSON, КодировкаТекста.UTF8);
// Отправка запроса
ИмяФайлаОтвета = ПолучитьИмяВременногоФайла();
HTTP.ОтправитьДляОбработки(Запрос, ИмяФайлаОтвета);
// Чтение ответа
ФайлОтвета = Новый ТекстовыйДокумент;
ФайлОтвета.Прочитать(ИмяФайлаОтвета, КодировкаТекста.UTF8);
ОтветСервера = ФайлОтвета.ПолучитьТекст();
Возвращать ОтветСервера;
КонецФункции
Применим соответствующий код обработчика на стороне PHP:
<?php
// Получаем сырые данные из тела запроса
$input = file_get_contents('php://input');
if (!empty($input)) {
// Декодируем JSON в ассоциативный массив
$data = json_decode($input, true);
if (isset($data['name'])) {
echo $data['name']; // Выведет: Ivan
} else {
echo "Ключ name не найден";
}
} else {
echo "empty";
}
?>
Если специфика вашего веб-сервера требует использования формата application/x-www-form-urlencoded и передачи данных через переменную (например, user=...), необходимо правильно закодировать JSON-строку средствами 1С и декодировать её на стороне PHP.
Посмотрим на пример формирования запроса в 1С:
&НаСервере
Функция ОтправитьPOSTПараметр()
Сервер = "192.168.0.68";
Ресурс = "/123.php";
HTTP = Новый HTTPСоединение(Сервер);
Данные = Новый Структура;
Данные.Вставить("name", "Ivan");
// Отключаем переносы строк
ПараметрыJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку(ПараметрыJSON);
ЗаписатьJSON(ЗаписьJSON, Данные);
ТекстJSON = ЗаписьJSON.Закрыть();
// Обязательное URL-кодирование строки
ЗакодированныйJSON = КодироватьСтроку(ТекстJSON, СпособКодированияСтроки.КодировкаURL);
Запрос = Новый HTTPЗапрос(Ресурс);
Запрос.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
// Передаем параметр и значение
Запрос.УстановитьТелоИзСтроки("user=" + ЗакодированныйJSON, КодировкаТекста.UTF8);
ИмяФайлаОтвета = ПолучитьИмяВременногоФайла();
HTTP.ОтправитьДляОбработки(Запрос, ИмяФайлаОтвета);
КонецФункции
Разберем принятие такого запроса на стороне PHP:
<?php
if (!empty($_POST['user'])) {
// Декодируем JSON-строку из POST-параметра
$userData = json_decode($_POST['user'], true);
echo $userData['name']; // Выведет: Ivan
} else {
echo "empty";
}
?>
Соответствие вместо Структура убедитесь, что все ключи имеют тип Строка. В противном случае метод ЗаписатьJSON() вызовет ошибку выполнения.UTF-8 как при формировании тела запроса в УстановитьТелоИзСтроки(), так и при чтении ответа через ТекстовыйДокумент.Прочитать().ЗаписатьЗначениеJSON(), что существенно сокращает объем кода.