Как вызвать готовую функцию на PHP из 1С без ее переписывания?

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

В практике разработки на платформе 1С периодически возникают ситуации, когда требуется применить сложный алгоритм (например, расчет оптимального логистического маршрута, сложную математическую обработку или специфическое шифрование), который уже реализован и протестирован на PHP. Переписывать такой код на встроенный язык 1С бывает нецелесообразно из-за трудоемкости или риска внесения ошибок.

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

Вариант 1. Запуск PHP-скрипта через консоль (CLI) с обменом через JSON

Самый простой способ интеграции без развертывания веб-серверов — запуск скрипта через интерпретатор командной строки php.exe. Однако при передаче сложных структур данных (массивов точек маршрута, таблиц) передавать параметры строкой в аргументах команды не рекомендуется: операционная система накладывает ограничения на длину командной строки, а также могут возникнуть искажения кодировок (Windows-1251, CP866 и UTF-8).

Наиболее надежный механизм — передача данных через временные файлы в формате JSON. Рассмотрим пошаговый процесс реализации этой схемы.

  1. Формирование входного файла в 1С. Собираем массив или структуру данных, сериализуем в JSON с помощью объектов ЗаписьJSON и функции ЗаписатьJSON(), после чего сохраняем во временный файл.
  2. Запуск процесса. Вызываем интерпретатор PHP. Вместо устаревшего метода КомандаСистемы лучше использовать ЗапуститьПриложение(), так как он позволяет скрыть окно консоли, дождаться завершения расчета и получить код возврата.
  3. Обработка на стороне PHP. Скрипт принимает путь к входному и выходному файлам через аргументы $argv, считывает JSON через file_get_contents(), декодирует его в массив функцией json_decode(), выполняет расчетную функцию и сохраняет результат в выходной JSON-файл.
  4. Чтение результата в 1С. С помощью объектов Чтение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)
    ];
}

Вариант 2. Развертывание локального HTTP-сервиса на PHP

Если расчеты производятся часто или требуется более чистое архитектурное разделение, оптимальным решением будет оформление 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.Закрыть();
КонецЕсли;

Важные системные нюансы и ограничения

Проанализируем технические моменты, на которые следует обратить внимание при настройке взаимодействия:

  1. Контекст выполнения на сервере 1С. Если запуск PHP-скрипта выполняется в серверном модуле или фоновом задании, процесс стартует от имени учетной записи службы 1С (например, USR1CV8). У этого пользователя должны быть права на запуск php.exe и доступ к каталогу временных файлов.
  2. Профили безопасности. Если в кластере серверов 1С включены профили безопасности или конфигурация работает в безопасном режиме, системные вызовы ЗапуститьПриложение и обращение к COM-объектам могут быть заблокированы. В таких условиях интеграция через HTTPСоединение является единственным рабочим вариантом.
  3. Таймауты и производительность. Для длительных вычислений в конструкторе HTTPСоединение следует явно задавать таймаут ожидания ответа, чтобы предотвратить зависание сеанса пользователя. При объемах расчетов от нескольких минут целесообразно переводить вызов в асинхронный режим через фоновые задания 1С.
← На главную