Интеграция с 1С: способы передачи данных через PHP

Раздел: Бизнес-приложения -> ERP системы

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

Основной подход: обмен через CommerceML с помощью cURL

Наиболее распространённый способ интеграции 1С с сайтами на PHP - использование протокола CommerceML (Common Markup Language). 1С отправляет XML-файлы по HTTP на скрипт PHP, который обрабатывает их и возвращает результат. PHP-скрипт выступает в роли веб-сервиса.

Как настроить обмен данными между 1С и PHP-сайтом через HTTP-запросы?

Для приёма данных от 1С используется стандартный скрипт (например, exchange.php). Он принимает POST-запрос с XML-данными.


// exchange.php - пример обработки CommerceML из 1С
$mode = $_GET['mode'] ?? ''; // 'catalog' или 'sale'
$type = $_GET['type'] ?? ''; // 'import' или 'checkauth' и т.д.

// 1. Аутентификация (проверка auth)
if ($type === 'checkauth') {
    // возврат сессии
    header('Content-Type: text/plain; charset=utf-8');
    echo "success\n";
    echo session_id()."\n";
    exit;
}

// 2. Инициализация
if ($type === 'init') {
    // возврат параметров обмена
    header('Content-Type: text/plain; charset=utf-8');
    echo "zip=no\n";
    echo "file_limit=10485760\n";
    exit;
}

// 3. Загрузка файла
if ($type === 'file') {
    $file = file_get_contents('php://input');
    // сохраняем или обрабатываем XML
    $xml = simplexml_load_string($file);
    // ... обработка
    header('Content-Type: text/plain; charset=utf-8');
    echo "success\n";
    exit;
}

1c exchange php type (обмен данными с 1с через php)

Со стороны 1С настраивается HTTP-сервис, указывающий на этот скрипт.

Типичные проблемы:

  • Неправильная кодировка (файлы должны быть в UTF-8).
  • Ошибка аутентификации (1С посылает Basic Auth, нужно настроить проверку).
  • Превышение лимита размера файла (настройки php.ini: post_max_size, upload_max_filesize).
  • Некорректный XML (отсутствие соответствующей библиотеки для парсинга).

Как упростить интеграцию с помощью готовой библиотеки для PHP?

Существует открытая PHP-библиотека 1c_exchange, реализующая протокол CommerceML. Она берёт на себя аутентификацию, обработку файлов и генерацию ответов.


// Пример работы с библиотекой 1c_exchange
require_once 'vendor/autoload.php';
use OpenData\OneCExchange\Exchange;

$exchange = new Exchange([
    'auth' => ['login' => 'admin', 'password' => 'pass'],
    'temp_dir' => '/tmp/1c_exchange/',
]);

$exchange->run();

Библиотека автоматически обрабатывает запросы типов checkauth, init, file, import. Требуется только реализовать классы для обработки данных (каталог, заказы).

Проблема: если версия библиотеки устарела, может не поддерживать новые версии CommerceML. Рекомендуется тестировать перед использованием.

Как реализовать обмен через SOAP, если 1С предоставляет веб-сервисы?

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


// SOAP клиент для 1С
$wsdl = 'http://1c-server/ws/Exchange1C?wsdl';
$client = new SoapClient($wsdl, [
    'login' => 'user',
    'password' => 'pass',
]);

try {
    $result = $client->getCatalog(['Date' => '2024-01-01']);
    // обрабатываем ответ
    var_dump($result);
} catch (SoapFault $e) {
    echo "Ошибка: " . $e->getMessage();
}

Этот вариант подходит, если 1С явно публикует SOAP-сервисы и требуется выгрузить данные по расписанию.

Ошибки: неверный WSDL, проблемы с аутентификацией, разные схемы XML.

Как организовать обмен без HTTP, используя XML-файлы на FTP или в локальной папке?

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


// скрипт для обработки XML из папки
$files = glob('/exchange/import/*.xml');
foreach ($files as $file) {
    $xml = simplexml_load_file($file);
    // обработка
    // после успеха перемещаем файл
    rename($file, '/exchange/processed/'.basename($file));
}

Минус: нет мгновенной обратной связи, требуется настройка планировщика.

Как обмениваться с 1С через REST, если она доработана?

Современные версии 1С могут публиковать REST API через HTTP-сервисы. PHP обращается к эндпоинтам, передавая данные в JSON или XML.


// Пример запроса к REST-сервису 1С
$ch = curl_init('http://1c-server/api/catalog');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'user:pass');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);

Этот вариант наиболее гибкий, но требует доработки 1С программистом.

Выбор конкретного подхода зависит от возможностей 1С, требований к синхронизации и инфраструктуры проекта.

Расширенные примеры кода для реализации обмена данными между 1С и PHP с дополнительными возможностями.

Потоковая обработка больших CommerceML-файлов

При объёме данных более 100 МБ стандартные методы (simplexml) потребляют много памяти. Используется XMLReader.

Пример

// Обработка CommerceML потоком XMLReader
$reader = new XMLReader();
$reader->open('import.xml');

while ($reader->read()) {
    if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'Товар') {
        $xmlProduct = $reader->readOuterXML();
        $product = simplexml_load_string($xmlProduct);
        // сохранить товар в БД
        echo "Обработан товар: " . $product->Наименование . PHP_EOL;
    }
}
$reader->close();
Обработан товар: Стул офисный
Обработан товар: Стол письменный
... (всего 10000 записей)

Выгрузка заказов из PHP в 1С (CommerceML)

Генерация XML-файла для отправки в 1С через any способ (HTTP, FTP).

Пример

// Генерация CommerceML для документа продажи
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><КоммерческаяИнформация>');
$doc = $xml->addChild('Документ');
$doc->addChild('Ид', 'ORDER-001');
$doc->addChild('Номер', '001');
$doc->addChild('Дата', date('Y-m-d'));
$doc->addChild('ХозОперация', 'Заказ товара');
$sum = $doc->addChild('Сумма', 15000.00);
$sum->addAttribute('Валюта', 'руб');

$products = $doc->addChild('Товары');
$item = $products->addChild('Товар');
$item->addChild('Ид', 'PROD-123');
$item->addChild('ЦенаЗаЕдиницу', 5000);
$item->addChild('Количество', 3);
$item->addChild('Сумма', 15000);

$xml->asXML('/tmp/order-export.xml');
echo 'Файл создан: /tmp/order-export.xml';
Файл создан: /tmp/order-export.xml

Параллельный обмен с несколькими базами 1С через Guzzle

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

Пример

require 'vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;

$clients = [
    ['base_uri' => 'http://1c-buh', 'auth' => ['user1', 'pass1']],
    ['base_uri' => 'http://1c-trade', 'auth' => ['user2', 'pass2']],
];

$requests = function () use ($clients) {
    foreach ($clients as $cfg) {
        $client = new Client(['base_uri' => $cfg['base_uri']]);
        yield new Request('POST', '/exchange', [
            'auth' => $cfg['auth'],
            'body' => file_get_contents('catalog.xml')
        ]);
    }
};

$pool = new Pool(new Client(), $requests(), [
    'concurrency' => 2,
    'fulfilled' => function ($response, $index) {
        echo "База #$index ответила: " . $response->getBody() . PHP_EOL;
    },
    'rejected' => function ($reason, $index) {
        echo "База #$index ошибка: " . $reason . PHP_EOL;
    },
]);
$promise = $pool->promise();
$promise->wait();
База #0 ответила: success
База #1 ответила: success

Обработка ошибок и повторные попытки при обмене с 1С

Реализация устойчивого обмена с логированием и автоматическими повторами при временных сбоях.

Пример

class ExchangeWithRetry {
    private $maxAttempts = 3;
    private $delay = 2; // секунды

    public function send($url, $xml) {
        $attempt = 0;
        while ($attempt < $this->maxAttempts) {
            $attempt++;
            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/xml']);
            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            if ($httpCode === 200) {
                echo "Успех на попытке $attempt\n";
                return $response;
            } else {
                echo "Ошибка (HTTP $httpCode) на попытке $attempt\n";
                if ($attempt < $this->maxAttempts) {
                    sleep($this->delay);
                }
            }
        }
        throw new \RuntimeException('Не удалось отправить данные после '.$this->maxAttempts.' попыток');
    }
}

$exchanger = new ExchangeWithRetry();
try {
    $exchanger->send('http://1c-server/exchange', '...');
} catch (Exception $e) {
    echo $e->getMessage();
}
Ошибка (HTTP 500) на попытке 1
Ошибка (HTTP 500) на попытке 2
Успех на попытке 3

Обмен данными с 1С через PHP - comments

En
1c exchange php type (php)