Разборка-сборка XML




Принцип обмена данными из 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='\

32 Comments

  1. stormtg

    Хм, интересный взгляд, спасибо посмотрим

    Reply
  2. fixin

    (1) ну что вы, это хит… взлетит еще…

    Reply
  3. Aragorn

    надо будет попробовать, только жалко инфорублей нет

    Reply
  4. necropunk

    Хм… Потестируем. Писал похожую вещь когда-то, интересно будет сравнить.

    Reply
  5. fzt

    Хм, а подключить через ActiveX готовый скрипт на VBS было бы проще.

    Работу посмотрел — понравилось. Но её действительно было возможно избежать.

    Reply
  6. fixin

    (5) смысл? суть этой разработки — работать с XML через привычный объект дерево. Т.е. тупой 1сник может ничего не знать об XML и тем не менее, с ним работать. Особенно актуально для тех, кто до сих пор использует DBF.

    Reply
  7. fzt

    Солидарен, в такой форме постановки вопроса я тоже думаю что актуально =)

    За offtopом можно оставить актуальность самого мм.. специалиста — как пользователя.

    Reply
  8. Новиков

    мне не понятно, зачем использовать это, вместо того, что используется в типовых как де-факто?

    Reply
  9. fixin

    (8) а что именно используется в типовых де-факто?

    Моя разработка — для упрощения разбора XML для тех, кто там ни в зуб ногой. Но кто хорошо знает саму 1С и работу с деревом значений.

    Да и сам я юзал эту функцию, когда юзал HTTP запросы. Там ответы приходили в виде небольшого XML и мне было проще кинуть ответ в дерево значений, чем писать парсингъ XML.

    (7) че то я не понял о чем вы.

    Reply
  10. Новиков

    (9) а что мешает открыть и взглянуть? 🙂 Мне кажется, у вас — велосипед. Я не говорю, что это плохо. Просто хотелось понять — а зачем он, если можно утащить сие из типовой, с аналогичной функциональностью? 🙂

    Reply
  11. fixin

    (10) я работаю с типовыми. Но до сих пор не могу понять, о чем вы собственно, ведете речь. Может это и велосипед, но это именно инструмент для тех, кому неохота париться с ХМЛ. Бац-бац и вместо ХМЛ уже дерево значений.

    А вы о чем речь ведете? Что-то я никак не пойму ваших намеков.

    Reply
  12. iotkin

    Большое спасибо за обработку. С удовольствием плюсую!!!

    Reply
  13. KliMich

    Спасибо! Интересный подход

    Reply
  14. premierex

    Минус — только за стиль программирования. Чтобы использовать этот код в своих целях, его придётся полностью переписывать! Важно не только то, ЧТО ты написал, но ещё и КАК ты это написал. Народ, как такой код читается, легко?

    Кстати, на ИТС есть рекомендации по оформлению кода от 1С. Советую ознакомиться!

    Reply
  15. fixin

    (14) код писал давно, возможно форматирование еще старое. Я потом перешел на нормальное.

    Но чтобы юзать, достаточно только вызывать нужную функцию. Не вижу проблем.

    Reply
  16. AlexO

    Загружал файл более 10Мб — зависла обработка.

    Пробовал несколько раз.

    и нет поиска.

    Reply
  17. fixin

    (16) а что вы хотели. Это тулза для чтения небольших XML. Она ведь разбирает XML в дерево. А размер коллекций в 1С ограничен. Для чтения больших ХМЛ юзайте ЧтениеХМЛ.

    Reply
  18. AlexO

    Сергей, если интересно — могу сбросить xml

    Reply
  19. AlexO

    (18)

    тогда печально все….

    ЧТо за обработка «ЧтениеХМЛ»? что вы под ней подразумеваете?

    Reply
  20. AlexO

    И данная обработка — только для файлов до 5МБ?

    Reply
  21. fixin

    (19)(20)

    ничего печального нет. Часто надо парсить маленькие XML.

    А большие XML в любом случае надо читать через последовательное чтение. В 1с для этого есть объект ЧтениеXML.

    Вообще существуют два способа разбора XML — или вы его целиком загружаете в память (как в моем методе) или последовательно читаете из файла.

    Чудес не бывает.

    Reply
  22. Magister

    Делал относительно недавно что-то наподобии, но ещё и с автоматическим преобразованием типов — как простых, так и ссылочных.

    Соответствие типов задается через макет, так же контроль заполненности реквизитов.

    Стоит публиковать?

    Reply
  23. fixin

    (22) если ты не заново изобрел XDTO, то публикуй

    Reply
  24. AlexO

    Кстати, а ведь есть XML_парсеры, которые прекрасно и быстро грузят много мегабайтные xml-ки в дерево…

    Reply
  25. fixin

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

    Reply
  26. AlexO

    (25)

    т.е. с коллекцией Дерево в 1с какие-то проблемы?

    ведь в тех, других, парсерах тоже в дереве все выводится…

    насчет памяти не скажу, но очень быстро.

    Reply
  27. fixin

    (26) у меня тоже в дерево все очень быстро выводится. Но огромное дерево просто тупо вешает 1с. Проблема была именно в этом. 😉 Кстати, большие XML файлы поэтому и не читаются через парсеры а-ля DOM, что памяти не хватает. Только последовательно!

    Reply
  28. AlexO

    (27)

    ну хотите, поделюсь парсером — и не вешает, и открывает большие файлы ))

    внутри еще не копался — не скажу, DOM там, или не DOM…

    Reply
  29. fixin

    (28) делитесь, но смотреть некогда. 😉

    Reply
  30. AlexO

    (29)

    с сайта MyKoD.info:

    Reply
  31. AlexO

    (29)

    или вот, разработала некая девушка Маша, доработал o-Planet:

    парсер XML

    Reply
  32. fixin

    (30)(31) и какие файлы ты туда пробовал заливать по размеру? 10-мбайтовый файл пробовал загружать?

    Reply

Leave a Comment

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