В практике разработки на платформе 1С периодически возникают ситуации, когда требуется применить сложный алгоритм (например, расчет оптимального логистического маршрута, сложную математическую обработку или специфическое шифрование), который уже реализован и протестирован на PHP. Переписывать такой код на встроенный язык 1С бывает нецелесообразно из-за трудоемкости или риска внесения ошибок.
Разберем основные архитектурные подходы, позволяющие вызывать готовые PHP-скрипты напрямую из 1С, передавать в них массивы и структуры параметров, а также получать результат вычислений обратно в информационную базу.
Самый простой способ интеграции без развертывания веб-серверов — запуск скрипта через интерпретатор командной строки php.exe. Однако при передаче сложных структур данных (массивов точек маршрута, таблиц) передавать параметры строкой в аргументах команды не рекомендуется: операционная система накладывает ограничения на длину командной строки, а также могут возникнуть искажения кодировок (Windows-1251, CP866 и UTF-8).
Наиболее надежный механизм — передача данных через временные файлы в формате JSON. Рассмотрим пошаговый процесс реализации этой схемы.
ЗаписьJSON и функции ЗаписатьJSON(), после чего сохраняем во временный файл.КомандаСистемы лучше использовать ЗапуститьПриложение(), так как он позволяет скрыть окно консоли, дождаться завершения расчета и получить код возврата.$argv, считывает JSON через file_get_contents(), декодирует его в массив функцией json_decode(), выполняет расчетную функцию и сохраняет результат в выходной JSON-файл.ЧтениеJSON и метода ПрочитатьJSON() считываем итоговую структуру данных в переменную 1С, после чего удаляем временные файлы.Посмотрим на пример формирования вызова на встроенном языке 1С:
// Подготовим входные данные (например, точки маршрута)
ВходныеДанные = Новый Массив;
ВходныеДанные.Добавить(Новый Структура("Широта,Долгота", 55.7558, 37.6173));
ВходныеДанные.Добавить(Новый Структура("Широта,Долгота", 59.9343, 30.3351));
ПутьКВходномуФайлу = ПолучитьИмяВременногоФайла("json");
ПутьКВыходномуФайлу = ПолучитьИмяВременногоФайла("json");
// Записываем данные в JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(ПутьКВходномуФайлу, "UTF-8");
ЗаписатьJSON(ЗаписьJSON, ВходныеДанные);
ЗаписьJSON.Закрыть();
// Формируем команду запуска php.exe
ПутьКИнтерпретатору = "C:\php\php.exe";
ПутьКСкрипту = "C:\scripts\route_calculator.php";
КоманднаяСтрока = СтрШаблон("%1 ""%2"" ""%3"" ""%4""",
ПутьКИнтерпретатору, ПутьКСкрипту, ПутьКВходномуФайлу, ПутьКВыходномуФайлу);
// Запускаем скрытно с ожиданием завершения
КодВозврата = 0;
ЗапуститьПриложение(КоманднаяСтрока, , Истина, КодВозврата);
Если КодВозврата = 0 Тогда
// Считываем результат работы PHP
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьФайл(ПутьКВыходномуФайлу, "UTF-8");
РезультатРасчета = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
КонецЕсли;
// Удаляем временные файлы
УдалитьФайлы(ПутьКВходномуФайлу);
УдалитьФайлы(ПутьКВыходномуФайлу);
Разберем код принимающего PHP-скрипта (файл route_calculator.php):
<?php
$inputFile = $argv[1];
$outputFile = $argv[2];
$rawJson = file_get_contents($inputFile);
$points = json_decode($rawJson, true);
// Вызываем существующую функцию расчета
$result = calculateOptimalRoute($points);
file_put_contents($outputFile, json_encode($result, JSON_UNESCAPED_UNICODE));
function calculateOptimalRoute($points) {
// Готовая логика на PHP
return [
"status" => "success",
"distance" => 712.5,
"points_count" => count($points)
];
}
Если расчеты производятся часто или требуется более чистое архитектурное разделение, оптимальным решением будет оформление PHP-кода в виде микросервиса (REST API). Для этого даже не обязательно настраивать Apache или Nginx: встроенный сервер PHP можно запустить одной командой php -S 127.0.0.1:8080.
В этом случае платформа 1С общается со скриптом через стандартные объекты HTTPСоединение, HTTPЗапрос и HTTPОтвет.
Рассмотрим пример отправки HTTP-запроса из 1С:
// Создаем соединение с сервером PHP
Соединение = Новый HTTPСоединение("127.0.0.1", 8080, , , , 30);
// Формируем тело запроса
ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет);
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписи);
ЗаписатьJSON(ЗаписьJSON, ВходныеДанные);
СтрокаТела = ЗаписьJSON.Закрыть();
// Настраиваем запрос POST
Запрос = Новый HTTPЗапрос("/calculate");
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Запрос.УстановитьТелоИзСтроки(СтрокаТела, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
// Отправляем данные и получаем ответ
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если Ответ.КодСостояния = 200 Тогда
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
РезультатРасчета = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
КонецЕсли;
Проанализируем технические моменты, на которые следует обратить внимание при настройке взаимодействия:
USR1CV8). У этого пользователя должны быть права на запуск php.exe и доступ к каталогу временных файлов.ЗапуститьПриложение и обращение к COM-объектам могут быть заблокированы. В таких условиях интеграция через HTTPСоединение является единственным рабочим вариантом.HTTPСоединение следует явно задавать таймаут ожидания ответа, чтобы предотвратить зависание сеанса пользователя. При объемах расчетов от нескольких минут целесообразно переводить вызов в асинхронный режим через фоновые задания 1С.