Универсальный механизм общения с внешним миром. HTTPЗапрос POST / GET / JSON




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

17 Comments

  1. neyasytyf

    Так это же для 8.3.

    http://v8.1c.ru/o7/201410json/index.htm

    Reply
  2. agent00mouse

    (1) neyasytyf, Наверняка 8.3. Значит со временем функция мутировала. Спасибо.

    Reply
  3. Lenten

    1) Чето у меня ругается. Платформа 1С:Предприятие 8.3 (8.3.5.1517)

    {Форма.Форма.Форма(55,28)}: Тип не определен (ЗаписьJSON)

    СтрокаJSON = Новый <<?>>ЗаписьJSON; СтрокаJSON.УстановитьСтроку(); (Проверка: Толстый клиент (обычное приложение))

    {Форма.Форма.Форма(100,36)}: Тип не определен (ЧтениеJSON)

    Чтение = Новый <<?>>ЧтениеJSON; (Проверка: Толстый клиент (обычное приложение))

    {Форма.Форма.Форма(116,36)}: Тип не определен (ЧтениеJSON)

    Чтение = Новый <<?>>ЧтениеJSON; (Проверка: Толстый клиент (обычное приложение))

    2) А что будет логином и паролем в случае с гуглом. Я вообще в этом не секу )

    Reply
  4. agent00mouse

    (3) Lenten, Логин и пароль были вырваны из контекста, просто для примера.

    ЧтениеJSON — появился в платформе начиная с релиза 8.3.6…

    Reply
  5. depresnjak

    Как по мне, то тема https и ssl раскрыта не полностью.

    Reply
  6. agent00mouse

    (5) depresnjak, Согласен, Мне базовой уровень авторизации пока было достаточно. Есть наработка по авторизации через сертификат, Всё выльется в небольшую библиотеку.

    Будут просьбы расширить функционал, постараюсь дописать.

    Reply
  7. sss999

    Можешь подсказать по коду?

    Reply
  8. agent00mouse

    (7) sss999, Что?

    Reply
  9. adhocprog

    Спасибо! Полезный материал )

    Reply
  10. unpete

    Порты 80 и 443, наверное, следует задавать только в том случае, если они не указаны в url.

    Ваш код отработает с ошибкой для запроса вида https://mysite.com:8359/data.json#private

    Reply
  11. agent00mouse

    (10) unpete, (10) unpete, Дельное замечание. поправлю.

    Reply
  12. Stepa86

    В УП и видимо в других конфах со встроенной библиотекой интернет-поддержки пользователей есть метод

    ИнтернетПоддержкаПользователейКлиентСервер.ЗагрузитьСодержимоеИзИнтернет(
    Знач URL,
    Знач Логин = Неопределено,
    Знач Пароль = Неопределено,
    ДопПараметры = Неопределено) Экспорт
    Reply
  13. Djo82

    Здравствуйте! не могли бы помочь, не могу понять как должен выглядеть параметр:

    ТелоЗапроса, не получается заменить значения на сайте методом post

    HTTPЗапрос    = Новый HTTPЗапрос(Ресурс, ЗаголовокHTTP);
    HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8);
    
    
    МассивДанныхJSON = Новый Массив;
    СтруктураДанныхJSON = Новый Структура;
    тДанные = Новый Структура;
    тДанные.Вставить(«managerComment», «тестКомментарий23»);
    тДанные.Вставить(«phone», 8888888);
    МассивДанныхJSON.Добавить(тДанные);
    
    СтрокаJSON = Новый ЗаписьJSON;
    СтрокаJSON.УстановитьСтроку();
    ЗаписатьJSON(СтрокаJSON, МассивДанныхJSON);
    ТелоЗапроса = СтрокаJSON.Закрыть();
    Параметры.ТекстЗапроса = ТелоЗапроса;
    //////

    Показать

    сама строка методом get:

    {«error»:»»,»errorMessage»:»»,»result»:[{«userType»:1,»managerID»:»1″,»managerLogin»:»manager»,»officeID»:»1″,»officeName»:»Нскойл»,»customerID»:»1″,»customerExternalID»:null,»categoryID»:»1″,»categoryName»:»розница»,»name»:null,»secondName»:null,»surname»:null,»fullName»:»»,»login»:null,»phone»:null,»mobilePhone»:null,»email»:null,»icq»:null,»skype»:null,»country»:null,»region»:null,»city»:null,»organizationName»:»Нскойл»,»businessID»:null,»businessName»:null,»balance»:»0.00″,»creditLimit»:null,»managerComment»:null,»contragentType»:»2″,»organizationFormID»:null,»organizationFormName»:null,»groupID»:null,»groupName»:null,»aiBalanceOrdered»:»0.00″,»aiBalanceActiveOrdered»:»0.00″,»aiBalanceTotal»:»0.00″,»aiBalanceByReturn»:»0.00″,»aiBalanceDelayed»:»0.00″}]}

    Reply
  14. Djo82

    (13) Сам спросил, сам отвечу)

    Возможно кому то понадобиться:

    Думал проблема с написанием текста запроса, оказалось с кодировкой

    Заголовок1.Добавить( Новый Структура(«Парам, Знч»,    «Content-Type»,        «application/json») );

    заменил на

    Заголовок1.Добавить( Новый Структура(«Парам, Знч»,    «Content-Type»,        «application/x-www-form-urlencoded;charset=utf-8») );
    

    и

    HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8);

    заменил на

    HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса,КодировкаТекста.UTF8,ИспользованиеByteOrderMark.НеИспользовать);
    Reply
  15. agent00mouse

    Вот оно как! 😉

    Прошу прощения, что сам не успел ответить. Не было времени. (отмазка)

    Reply
  16. Lion_LexXx

    Получение IAM-токена с помощью PowerShell:

    $yandexPassportOauthToken = «<OAuth-Token>»

    $Body = @{ yandexPassportOauthToken = «$yandexPassportOauthToken» } | ConvertTo-Json -Compress

    Invoke-RestMethod -Method ‘POST’ -Uri ‘https://iam.api.cloud.yandex.net/iam/v1/tokens’ -Body $Body -ContentType ‘Application/json’ | Select-Object -ExpandProperty iamToken

    Как это переделать на 1С?

    Reply
  17. Lion_LexXx

    (16)

    https://infostart.ru/public/1113219/

        АдресСервера = «iam.api.cloud.yandex.net»;
    yandexPassportOauthToken = «ХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХХ»;
    ssl = Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаWindows( СпособВыбораСертификатаWindows.Выбирать), Новый СертификатыУдостоверяющихЦентровWindows());
    
    
    Соединение = Новый HTTPСоединение(АдресСервера,443,,,,20,ssl,Неопределено);
    Заголовки = Новый Соответствие;
    Заголовки.Вставить(«Content-Type», «application/json»);
    
    Запрос = Новый HTTPЗапрос(«/iam/v1/tokens»,Заголовки);
    СтрокаТела = «{«»yandexPassportOauthToken»»: «»» + yandexPassportOauthToken + «»»}»;
    Запрос.УстановитьТелоИзСтроки(СтрокаТела,КодировкаТекста.UTF8);
    
    
    Ответ = Соединение.ОтправитьДляОбработки(Запрос);
    Сообщить(«Нам вернули код » + Ответ.КодСостояния);
    Сообщить(Ответ.ПолучитьТелоКакСтроку());
    
    СтрокаОтвет = Ответ.ПолучитьТелоКакСтроку();
    
    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(СтрокаОтвет);
    СтруктураОтвета = ПрочитатьJSON(Чтение);
    iamToken = СтруктураОтвета.iamToken;

    Показать

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *