Как реализовать простой REST API на PHP для доступа к базе MySQL из 1С

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

В современной разработке на платформе 1С все чаще возникает задача интеграции с внешними базами данных, размещенными на Linux-хостингах. Использование традиционных ODBC-компонентов в таких условиях становится затруднительным: драйверы не всегда доступны, а облачные сервисы (например, 1С:Фреш) накладывают жесткие ограничения на использование внешних библиотек. Решением становится создание промежуточного слоя в виде REST API. Разберем подробно, как реализовать такой механизм на обычном PHP-хостинге, таком как Jino, и как правильно организовать взаимодействие со стороны 1С.

Зачем нужен REST API вместо прямого подключения к базе

Рассмотрим основные причины, по которым архитектура через HTTP-запросы выигрывает у прямого соединения. Во-первых, это кроссплатформенность. HTTP-запросы поддерживаются любой версией 1С (начиная с 7.7 через внешние компоненты и нативно в 8.x). Во-вторых, это безопасность. Вам не нужно открывать порт 3306 (MySQL) для всего интернета; достаточно оставить доступ только по 80 или 443 порту с авторизацией. В-третьих, 1С:Предприятие в тонком клиенте или веб-клиенте гораздо стабильнее работает с JSON, чем с тяжелыми драйверами баз данных.

Вариант 1: Простейший PHP-скрипт для выполнения запросов

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

Создадим файл api.php на вашем хостинге. Разберем по шагам его структуру:


<?php
// Настройки подключения к базе данных
$host = 'localhost';
$db   = 'your_database_name';
$user = 'your_username';
$pass = 'your_password';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

try {
     $pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
     header('Content-Type: application/json');
     echo json_encode(['error' => 'Connection failed: ' . $e->getMessage()]);
     exit;
}

// Простейшая проверка авторизации через заголовок (токен)
$headers = apache_request_headers();
$token = "my_secret_key_123";

if (!isset($headers['X-Auth-Token']) || $headers['X-Auth-Token'] !== $token) {
    header('HTTP/1.0 401 Unauthorized');
    echo json_encode(['error' => 'Unauthorized']);
    exit;
}

// Получаем SQL из POST-запроса
$sql = $_POST['sql'] ?? '';

if (empty($sql)) {
    echo json_encode(['error' => 'No SQL query provided']);
    exit;
}

try {
    $stmt = $pdo->query($sql);
    $data = $stmt->fetchAll();
    header('Content-Type: application/json');
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
    echo json_encode(['error' => 'Query error: ' . $e->getMessage()]);
}
?>

В данном примере мы используем объект PDO (PHP Data Objects). Это современный стандарт для работы с базами данных в PHP, который обеспечивает лучшую производительность и безопасность по сравнению со старыми функциями mysql_connect.

Вариант 2: Использование параметров вместо сырого SQL

Как отмечалось в обсуждении, передавать чистый текст SQL-запроса через интернет — небезопасно. Рассмотрим более правильный подход: передачу параметров. Это защитит вашу базу от SQL-инъекций.

Выясним причину, почему это лучше: когда вы передаете id запчасти как параметр, PHP-скрипт сам подставляет его в заранее подготовленный шаблон запроса. Проанализируем пример кода с использованием подготовленных выражений:


// Вместо выполнения любого SQL, создадим метод для поиска запчасти по артикулу
$article = $_GET['article'] ?? '';

if ($article) {
    $stmt = $pdo->prepare("SELECT id, name, price FROM parts WHERE article = ?");
    $stmt->execute([$article]);
    $result = $stmt->fetchAll();
    echo json_encode($result);
}

Настройка авторизации через .htaccess

Если вы не хотите прописывать логику авторизации внутри PHP, воспользуемся возможностями сервера Apache на хостинге Jino. Разберем, как ограничить доступ к вашему API на уровне сервера. Создайте в папке со скриптом файл .htaccess:


AuthType Basic
AuthName "Restricted Access"
AuthUserFile /home/users/y/yourname/.htpasswd
Require valid-user

Важный момент: на многих хостингах заголовки авторизации не пробрасываются в PHP автоматически. Чтобы 1С могла передать логин и пароль, добавьте в этот же файл следующую строку: SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1. Это позволит PHP видеть данные Basic Auth.

Реализация запроса на стороне 1С

Теперь посмотрим, как получить данные в 1С. Мы будем использовать объект HTTPСоединение и функции работы с JSON. Проанализируем пример кода на языке 1С:


Процедура ПолучитьДанныеИзMySQL()
    
    Сервер = "your-site.jino.ru";
    Токен = "my_secret_key_123";
    
    // Настраиваем защищенное или обычное соединение
    НТТР = Новый HTTPСоединение(Сервер, 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
    
    Запрос = Новый HTTPЗапрос("/api.php");
    Запрос.Заголовки.Вставить("X-Auth-Token", Токен);
    Запрос.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
    
    // Текст запроса (если используем вариант 1)
    ТекстЗапроса = "sql=" + "SELECT * FROM parts LIMIT 10";
    Запрос.УстановитьТелоИзСтроки(ТекстЗапроса, КодировкаТекста.UTF8);
    
    Попытка
        Ответ = НТТР.ОтправитьДляОбработки(Запрос);
        Если Ответ.КодСостояния = 200 Тогда
            ЧтениеJSON = Новый ЧтениеJSON;
            ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
            Данные = ПрочитатьJSON(ЧтениеJSON);
            ЧтениеJSON.Закрыть();
            
            // Теперь в переменной "Данные" у нас массив структур
            Для Каждого СтрокаИзБазы Из Данные Цикл
                Сообщить("Запчасть: " + СтрокаИзБазы["name"]);
            КонецЦикла;
        Иначе
            Сообщить("Ошибка сервера: " + Ответ.КодСостояния);
        КонецЕсли;
    Исключение
        Сообщить("Ошибка связи: " + ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

В этом коде мы используем метод ПрочитатьJSON(), который появился в платформе 8.3.6. Это крайне эффективный инструмент, который автоматически преобразует JSON-массив в Массив объектов 1С, а объекты — в Структура. Это избавляет программиста от ручного парсинга текста.

Продвинутые решения: PHP-CRUD-API

Если вам нужно полноценное API ко всей базе данных с поддержкой всех видов операций (Create, Read, Update, Delete), а писать код вручную нет времени, рассмотрим использование готовых библиотек. Одной из лучших является PHP-CRUD-API.

Это всего один файл, который вы загружаете на сервер. Выясним, как его настроить:

  1. Скачиваете файл api.php из репозитория проекта (легко найти в поиске).
  2. В начале файла прописываете данные для доступа к MySQL.
  3. Обращаетесь к нему из 1С по адресу: site.ru/api.php/records/название_таблицы.

Библиотека сама сформирует нужные SQL-запросы на основе параметров URL. Например, запрос site.ru/api.php/records/parts?filter=price,ge,1000 автоматически вернет все запчасти дороже 1000 рублей. Это избавляет от необходимости писать какой-либо SQL-код на стороне 1С и обеспечивает высокий уровень безопасности.

Оптимизация работы с большими данными

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

Таким образом, создание REST API на PHP для 1С — это не только способ обойти ограничения хостинга, но и переход к более современной и безопасной архитектуре обмена данными.

← На главную