Как правильно организовать загрузку файлов из 1С на PHP-сайт?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Интеграция 1С с веб-сервисами — это одна из наиболее частых задач при построении современных экосистем автоматизации. Одной из самых распространенных проблем является передача файлов (изображений, PDF-документов) на сервер под управлением PHP. В этой статье мы подробно разберем, как правильно сформировать запрос на стороне 1С и как корректно принять его на стороне PHP, чтобы избежать потери данных и ошибок 404 или 500.

Разбор типичных ошибок при создании HTTP-соединения

Проанализируем исходный код, который часто используют начинающие разработчики. Первая и самая важная ошибка кроется в инициализации объектов HTTPСоединение и HTTPЗапрос. Посмотрим на этот фрагмент:


HTTPСоединение = Новый HTTPСоединение("report.tmotor.ru"); // Только имя сервера
// ОШИБКА: Нельзя писать полный URL в HTTPЗапрос
HTTPЗапрос = Новый HTTPЗапрос("report.tmotor.ru/report/php/tel_upload.php", ЗаголовокHTTP); 

Выясним причину проблемы: объект HTTPСоединение отвечает за установку связи с хостом (сервером), а HTTPЗапрос должен содержать только относительный путь к ресурсу на этом сервере. Правильный подход выглядит так:

  1. Создаем HTTPСоединение, указывая только домен (например, "report.tmotor.ru").
  2. Создаем HTTPЗапрос, указывая путь от корня сайта (например, "/report/php/tel_upload.php").

Если в HTTPЗапрос передать строку, начинающуюся с имени домена или http://, сервер может вернуть ошибку, так как запрос будет сформирован некорректно на уровне протокола.

Формирование тела запроса в формате multipart/form-data

Для передачи файлов используется формат multipart/form-data. Этот формат требует строгого соблюдения структуры разделителей (boundary). Разберем по шагам, как правильно собрать тело запроса в 1С. Важно помнить, что протокол HTTP требует использования последовательности символов ВК + ПС (возврат каретки и перевод строки) в качестве разделителя строк, в то время как стандартный Символы.ПС в 1С — это только один символ перевода строки.

Рассмотрим пример правильного формирования текстового файла для отправки:


Разделитель = "----" + СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");
ИмяФайлаТела = ПолучитьИмяВременногоФайла();

ЗаписьТекста = Новый ЗаписьТекста(ИмяФайлаТела, КодировкаТекста.UTF8, Символы.ВК + Символы.ПС);
ЗаписьТекста.ЗаписатьСтроку("--" + Разделитель);
// Важно: name="fileToUpload" — это ключ, по которому PHP найдет файл в массиве $_FILES
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""fileToUpload""; filename=""image.png""");
ЗаписьТекста.ЗаписатьСтроку("Content-Type: image/png");
ЗаписьТекста.ЗаписатьСтроку(""); // Пустая строка перед данными

// Здесь мы можем записать бинарные данные или Base64
ЗаписьТекста.Записать(Base64Строка(ДвоичныеДанныеФайла)); 

ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку("--" + Разделитель + "--");
ЗаписьТекста.Закрыть();

Проанализируем ситуацию с Base64. Многие программисты 1С привыкли кодировать двоичные данные в Base64. Однако, если вы используете multipart/form-data, это не всегда эффективно, так как объем данных увеличивается на 33%. Если ваш PHP-скрипт умеет работать с бинарными данными, лучше передавать файл «как есть», используя Поток или комбинируя файлы.

Прием данных на стороне PHP: $_POST против $_FILES

Очень важно понимать, как PHP обрабатывает входящий запрос. Если в 1С вы указали Content-Disposition: form-data; name="file_data", то данные попадут в массив $_POST['file_data']. Если же вы добавили параметр filename="image.png", то PHP воспримет это как загрузку файла и поместит информацию в массив $_FILES['file_data'].

Посмотрим на пример PHP-скрипта, который корректно сохраняет файл, отправленный из 1С:


<?php
$target_dir = "uploads/";
// Проверяем, пришел ли файл через стандартный механизм загрузки
if(isset($_FILES["fileToUpload"])) {
    $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
    
    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
        echo "Файл успешно сохранен на сервере.";
    } else {
        echo "Ошибка при перемещении временного файла.";
    }
} else {
    echo "Данные о файле не получены.";
}
?>

Если вы все же решили передавать данные в формате Base64 внутри обычного поля POST, не забудьте на стороне PHP выполнить декодирование перед сохранением, иначе файл будет поврежден:


$encodedData = $_POST['file_data'];
$decodedData = base64_decode($encodedData);
file_put_contents("image.png", $decodedData);

Использование защищенного соединения (HTTPS)

Современные веб-сайты работают по протоколу HTTPS. В этом случае обычного объекта HTTPСоединение будет недостаточно, так как 1С должна проверить SSL-сертификат сервера. Для этого необходимо использовать объект ЗащищенноеСоединениеOpenSSL.

Разберем пример инициализации безопасного соединения:


Защита = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
HTTPСоединение = Новый HTTPСоединение("report.tmotor.ru", 443, , , , 30, Защита);

Без этого параметра 1С выдаст ошибку "Удаленный узел не прошел проверку", и запрос даже не дойдет до вашего PHP-скрипта.

Рекомендации по отладке интеграции

Если код написан, но файл не появляется на сервере, выполним следующие шаги:

  1. Проверка прав доступа: Убедитесь, что папка на сервере, в которую PHP пытается записать файл, имеет права на запись для пользователя веб-сервера (обычно www-data или apache).
  2. Настройки PHP.ini: Проверьте параметры upload_max_filesize и post_max_size. Если файл из 1С больше этих лимитов, сервер молча отбросит запрос.
  3. Логирование: Добавьте в начало PHP-скрипта строку file_put_contents('debug.txt', print_r($_FILES, true));. Это позволит увидеть, какие данные реально доходят до сервера.
  4. Использование внешних инструментов: Попробуйте отправить файл на этот же адрес через Postman. Если через него работает, а из 1С — нет, значит, проблема в формировании тела запроса или заголовков в коде 1С.

Соблюдение этих правил позволит вам создать надежный механизм обмена данными между 1С:Предприятие и веб-сайтом, обеспечив целостность передаваемой информации и корректную обработку на стороне сервера.

← На главную