Как выгрузить товары с PHP-сайта в 1С
Полное руководство по интеграции самописного PHP-сайта с 1С для выгрузки товаров и данных о продажах. Узнайте методы реализации, код примеров и решения для автоматизации обмена.
Как реализовать выгрузку товаров с самописного PHP-сайта в 1С?
Мы разрабатываем интернет-магазин на PHP с нуля (ранее использовали Битрикс, но требовался нестандартный функционал). Нам нужна интеграция с 1С, при которой:
- Товары ведутся в админке сайта
- Данные о товарах и продажах ежедневно выгружаются из базы сайта в 1С
- 1С используется исключительно для бухгалтерской отчетности
Возможно ли реализовать такой обратный обмен данными между сайтом и 1С, и насколько сложным будет этот процесс?
Выгрузка товаров с самописного PHP-сайта в 1С абсолютно возможна и реализуется через стандартный протокол обмена данными, разработанный 1C. Для этого потребуется создать специальный PHP-обработчик на сайте, который будет формировать файлы выгрузки в формате XML или CSV, и настроить ежедневное автоматическое выполнение этого процесса. Сложность реализации зависит от опыта разработчика, но при наличии базовых знаний PHP это вполне выполнимая задача.
Содержание
- Основные методы интеграции PHP-сайта с 1С
- Протокол обмена данными 1С и PHP
- Пошаговая реализация выгрузки товаров
- Настройка автоматического ежедневного обмена
- Обработка данных о продажах
- Решения для учета ограничений хостинга
- Альтернативные готовые решения
Основные методы интеграции PHP-сайта с 1С
Интеграция самописного PHP-сайта с 1С может быть реализована несколькими способами, каждый из которых имеет свои преимущества и особенности:
1. Обмен через файловый каталог (самый распространенный метод)
- PHP-сайт создает файлы выгрузки в специальной директории
- 1C регулярно проверяет эту директорию и импортирует данные
- Требует настройки прав доступа к директории обмена
2. Веб-сервисы и REST API
- 1C предоставляет REST интерфейс для внешних систем
- PHP-сайт отправляет запросы напрямую к 1C
- Позволяет двусторонний обмен в реальном времени
3. Прямое подключение к базе данных
- Наиболее сложный метод, требующий глубокого знания обеих систем
- Прямое чтение данных из базы сайта и запись в базу 1C
Для вашего случая, когда товары ведутся на сайте, а 1С используется только для отчетности, идеально подойдет первый метод - обмен через файловый каталог. Это надежно, не требует сложной настройки на стороне 1С и позволяет гибко управлять процессом выгрузки.
Протокол обмена данными 1С и PHP
1C использует открытый протокол обмена данными, который был разработан совместно 1C и 1C-Bitrix. Этот протокол стандартизирует формат выгрузки и импорта данных между разными системами.
Основные характеристики протокола:
- Поддержка форматов XML и CSV
- Возможность сжатия данных для больших объемов
- Поддержка частичной выгрузки (только измененных данных)
- Структурированный формат для товаров, категорий, остатков и заказов
Согласно документации 1C, протокол обмена включает следующие основные компоненты:
<?xml version="1.0" encoding="UTF-8"?>
<CommerceML>
<Каталог>
<Товары>
<Товар>
<Ид>unique_product_id</Ид>
<Наименование>Название товара</Наименование>
<БазоваяЕдиница>шт</БазоваяЕдиница>
<Цены>
<Цена>
<Представление>Розничная</Представление>
<Валюта>RUB</Валюта>
<ЦенаЗаЕдиницу>1000.00</ЦенаЗаЕдиницу>
</Цена>
</Цены>
</Товар>
</Товары>
</Каталог>
</CommerceML>
Для реализации этого протокола на PHP существует несколько готовых библиотек, например exchange1c от Bigperson, которая предоставляет готовые интерфейсы для работы с 1C.
Пошаговая реализация выгрузки товаров
Шаг 1: Подготовка структуры данных на сайте
Прежде чем реализовывать выгрузку, необходимо привести структуру товаров в базе сайта к формату, совместимому с 1С:
-- Пример структуры таблицы товаров
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
code VARCHAR(100) UNIQUE, -- Артикул/код товара
name VARCHAR(255), -- Наименование
description TEXT, -- Описание
price DECIMAL(10,2), -- Цена
currency VARCHAR(3) DEFAULT 'RUB',
quantity INT DEFAULT 0, -- Остаток
category_id INT, -- Категория
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Таблица категорий
CREATE TABLE categories (
id INT AUTO_INCREMENT PRIMARY KEY,
code VARCHAR(100) UNIQUE,
name VARCHAR(255),
parent_id INT NULL
);
Шаг 2: Создание PHP-обработчика выгрузки
Нужно создать скрипт, который будет формировать XML-файл выгрузки. Пример базовой реализации:
<?php
// config.php
$config = [
'exchange_dir' => './exchange/', // Директория для обмена
'login' => 'admin',
'password' => 'admin',
'use_zip' => true,
];
// exchange_handler.php
require_once 'config.php';
require_once 'vendor/autoload.php';
use Bigperson\Exchange1C\Exchange1C;
$exchange = new Exchange1C($config);
// Получаем товары из базы
$products = getProductsFromDatabase();
// Формируем XML
$xml = generateCommerceML($products);
// Сохраняем файл
$filename = 'products_' . date('Y-m-d_H-i-s') . '.xml';
$file_path = $config['exchange_dir'] . $filename;
file_put_contents($file_path, $xml);
if ($config['use_zip']) {
createZipArchive($file_path);
}
function getProductsFromDatabase() {
// Реализация подключения к БД и выборки товаров
$db = new PDO('mysql:host=localhost;dbname=shop', 'user', 'password');
$stmt = $db->query("SELECT * FROM products WHERE updated_at > DATE_SUB(NOW(), INTERVAL 1 DAY)");
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
function generateCommerceML($products) {
$xml = '<?xml version="1.0" encoding="UTF-8"?>';
$xml .= '<CommerceML><Каталог><Товары>';
foreach ($products as $product) {
$xml .= '<Товар>';
$xml .= '<Ид>' . htmlspecialchars($product['code']) . '</Ид>';
$xml .= '<Наименование>' . htmlspecialchars($product['name']) . '</Наименование>';
$xml .= '<БазоваяЕдиница>шт</БазоваяЕдиница>';
$xml .= '<Цены><Цена>';
$xml .= '<Представление>Розничная</Представление>';
$xml .= '<Валюта>' . htmlspecialchars($product['currency']) . '</Валюта>';
$xml .= '<ЦенаЗаЕдиницу>' . number_format($product['price'], 2) . '</ЦенаЗаЕдиницу>';
$xml .= '</Цена></Цены>';
$xml .= '</Товар>';
}
$xml .= '</Товары></Каталог></CommerceML>';
return $xml;
}
Шаг 3: Настройка прав доступа
Необходимо убедиться, что веб-сервер имеет права на запись в директорию обмена:
# На Linux системах
sudo chown -R www-data:www-data ./exchange/
sudo chmod -R 755 ./exchange/
Настройка автоматического ежедневного обмена
Для ежедневной выгрузки данных можно использовать несколько подходов:
1. Cron-задачи (рекомендуется)
# Добавить в crontab
0 2 * * * /usr/bin/php /path/to/your/site/exchange_handler.php >> /var/log/exchange.log 2>&1
2. Планировщик задач Windows (для Windows-серверов)
- Создать задачу, которая будет запускать PHP-скрипт ежедневно в указанное время
3. Демон через Supervisor
# /etc/supervisor/conf.d/exchange.conf
[program:exchange]
command=php /path/to/exchange_handler.php
autostart=true
autorestart=true
user=www-data
stdout_logfile=/var/log/exchange.log
4. Внутренний планировщик на PHP
// Можно реализовать через проверку времени последней выгрузки
$last_export = getLastExportTime();
if (strtotime($last_export) < strtotime('-1 day')) {
runExport();
}
function getLastExportTime() {
$file = './exchange/last_export.txt';
if (file_exists($file)) {
return file_get_contents($file);
}
return '1970-01-01';
}
Для обеспечения надежности рекомендуется добавлять логирование и обработку ошибок:
function logExport($message, $level = 'INFO') {
$log_file = './exchange/export.log';
$timestamp = date('Y-m-d H:i:s');
$log_entry = "[$timestamp] [$level] $message\n";
file_put_contents($log_file, $log_entry, FILE_APPEND);
}
try {
// Код выгрузки
logExport('Выгрузка товаров начата');
// ... логика выгрузки
logExport('Выгрузка товаров успешно завершена');
} catch (Exception $e) {
logExport('Ошибка выгрузки: ' . $e->getMessage(), 'ERROR');
// Отправка уведомления администратору
sendAdminNotification($e->getMessage());
}
Обработка данных о продажах
Для выгрузки данных о продажах необходимо создать отдельный файл или структуру в рамках одного XML-файла:
function generateSalesData($orders) {
$xml = '<КоммерческаяИнформация>';
$xml .= '<Документы>';
foreach ($orders as $order) {
$xml .= '<Документ>';
$xml .= '<Ид>' . $order['id'] . '</Ид>';
$xml .= '<Номер>' . $order['number'] . '</Номер>';
$xml .= '<Дата>' . $order['created_at'] . '</Дата>';
$xml .= '<ХозСубъект><Ид>your_company_id</Ид></ХозСубъект>';
$xml .= '<Контрагент><Ид>' . $order['customer_id'] . '</Ид></Контрагент>';
// Товары в заказе
$xml .= '<Товары>';
foreach ($order['items'] as $item) {
$xml .= '<Товар>';
$xml .= '<Ид>' . $item['product_code'] . '</Ид>';
$xml .= '<Наименование>' . htmlspecialchars($item['name']) . '</Наименование>';
$xml .= '<БазоваяЕдиница>шт</БазоваяЕдиница>';
$xml .= '<Количество>' . $item['quantity'] . '</Количество>';
$xml .= '<ЦенаЗаЕдиницу>' . number_format($item['price'], 2) . '</ЦенаЗаЕдиницу>';
$xml .= '</Товар>';
}
$xml .= '</Товары>';
$xml .= '</Документ>';
}
$xml .= '</Документы>';
$xml .= '</КоммерческаяИнформация>';
return $xml;
}
Для обработки больших объемов данных лучше реализовать построчную обработку:
function streamExport($filename) {
$file = fopen($filename, 'w');
fwrite($file, '<?xml version="1.0" encoding="UTF-8"?><CommerceML><Каталог><Товары>');
$db = new PDO('mysql:host=localhost;dbname=shop', 'user', 'password');
$stmt = $db->query("SELECT * FROM products WHERE updated_at > DATE_SUB(NOW(), INTERVAL 1 DAY)");
while ($product = $stmt->fetch(PDO::FETCH_ASSOC)) {
$xml = '<Товар>';
$xml .= '<Ид>' . htmlspecialchars($product['code']) . '</Ид>';
// ... остальные поля
$xml .= '</Товар>';
fwrite($file, $xml);
}
fwrite($file, '</Товары></Каталог></CommerceML>');
fclose($file);
}
Решения для учета ограничений хостинга
При разработке интеграции важно учитывать ограничения хостинг-провайдеров:
Проблемы, с которыми можно столкнуться:
- Ограничение на максимальное время выполнения скрипта
- Ограничение на объем памяти
- Отсутствие возможности установки расширений
- Ограничения на размер загружаемых файлов
Решения:
- Для ограничения времени выполнения:
// Увеличить лимит времени выполнения
set_time_limit(0); // Без ограничений
// или
set_time_limit(300); // 5 минут
// Обработка по частям
$max_execution_time = 300; // 5 минут
$start_time = time();
while (hasMoreProducts() && (time() - $start_time) < $max_execution_time) {
exportBatchOfProducts();
sleep(1); // Небольшая пауза
}
- Для ограничения памяти:
// Очистка памяти после каждой партии
function exportBatch($batch_size = 100) {
$offset = 0;
while (true) {
$products = getProductsBatch($offset, $batch_size);
if (empty($products)) break;
generateXmlForBatch($products);
$offset += $batch_size;
// Очистка памяти
unset($products);
gc_collect_cycles();
}
}
- Для ограничений на установку расширений:
// Использовать встроенные функции PHP вместо расширений
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->formatOutput = true;
$catalog = $xml->createElement('Каталог');
$xml->appendChild($catalog);
foreach ($products as $product) {
$product_node = $xml->createElement('Товар');
// ... добавление элементов
$catalog->appendChild($product_node);
}
- Для больших файлов:
// Сжатие данных
function createZipArchive($file_path) {
$zip = new ZipArchive();
$zip_filename = $file_path . '.zip';
if ($zip->open($zip_filename, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) {
$zip->addFile($file_path);
$zip->close();
unlink($file_path); // Удалить оригинальный файл
return $zip_filename;
}
return false;
}
Альтернативные готовые решения
Если вы не хотите реализовывать интеграацию с нуля, существуют готовые решения:
1. Библиотека exchange1c
exchange1c - готовая PHP-библиотека для интеграции с 1С:
require_once './vendor/autoload.php';
use Bigperson\Exchange1C\Config;
use Bigperson\Exchange1C\Exchange1C;
$config = new Config([
'import_dir' => '1c_exchange',
'login' => 'admin',
'password' => 'admin',
'use_zip' => false,
]);
$exchange = new Exchange1C($config);
$exchange->run();
2. Готовые модули для разных CMS
- Для OpenCart: модуль обмена с 1С
- PrestaShop: модуль обмена данными
- WooCommerce: плагин обмена с 1С
3. Ручная выгрузка через CSV
Если автоматическая интеграция слишком сложна, можно реализовать ручную выгрузку:
function exportToCsv() {
$filename = 'export_' . date('Y-m-d') . '.csv';
$file = fopen($filename, 'w');
// Заголовки CSV
fputcsv($file, ['ID', 'Артикул', 'Название', 'Цена', 'Остаток']);
// Данные товаров
$products = getProducts();
foreach ($products as $product) {
fputcsv($file, [
$product['id'],
$product['code'],
$product['name'],
$product['price'],
$product['quantity']
]);
}
fclose($file);
return $filename;
}
4. 1C Drive Integration
1C Drive предоставляет готовый механизм обмена через сетевую директорию с минимальными настройками на стороне PHP-сайта.
Источники
- Библиотека exchange1c на GitHub
- Интеграция 1C и WooCommerce
- Модуль обмена для OpenCart
- Документация 1C по протоколу обмена
- Методы интеграции с 1C:Enterprise
- 1C Drive guides
- PrestaShop модуль обмена с 1C
Заключение
Интеграция самописного PHP-сайта с 1С для выгрузки товаров и данных о продажах является вполне реальной задачей, которая может быть решена несколькими способами:
-
Наиболее простой и надежный метод - обмен через файловый каталог с использованием стандартизированного XML-формата CommerceML. Этот подход не требует сложной настройки на стороне 1С и позволяет гибко управлять процессом выгрузки.
-
Сложность реализации умеренная - базовые навыки PHP и понимание структуры данных 1C достаточны для создания работающей системы. Время разработки зависит от количества товаров и сложности структуры данных, но обычно составляет от нескольких дней до двух недель.
-
Для автоматизации процесса рекомендуется использовать cron-задачи или планировщик задач для ежедневной выгрузки с добавлением логирования и обработки ошибок.
-
При ограничениях хостинга важно реализовать обработку данных по частям, сжатие больших файлов и оптимизацию использования памяти.
-
Готовые решения в виде библиотек и модулей могут значительно ускорить разработку, особенно если вы не хотите реализовывать все с нуля.
Для вашего случая, когда 1С используется исключительно для бухгалтерской отчетности, идеально подходит односторонняя выгрузка данных с сайта. Такой подход обеспечит актуальность данных в 1С без необходимости обратного обмена, что значительно упростит систему интеграции.