Резервное копирование




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

13 Comments

  1. alexk-is

    С постановкой вопроса не согласен. Вот здесь есть список «альтернативных» решений http://www.infostart.ru/projects/3650/

    По поводу «ошибки формата потока» могу сказать только следующее:

    За базой данных нужно следить. Регулярно выполнять регламентные операции.

    А резервные копии обязаны быть. Это даже не вопрос.

    Reply
  2. gnataly

    Бесспорно есть много лучших альтернативных решений. Ваш вариант более профессионален.

    Мне нужен был инструмент другого рода. Мы пользуемся «ручной» архивацией в совокупности с автоматической. Там, где нет сисадминов и грамотных пользователей, способных проследить за результатами архивации (а вдруг архив не создался), проще научить бухгалтера пользоваться данной обработкой (по крайней мере нашим клиентам нравится больше, чем через конфигуратор).

    Когда некому следить за базой данных, а посещения специалистов нерегулярны, спасает единовременная архивация (мне просто лень каждый раз делать «*.dt», когда на компьютере 6 баз и более). Удобно — архив перед обновлением баз, архив после обновления и работы с клиентом. Может кому пригодится…

    Reply
  3. alexk-is

    При заполнении списка баз не корректно обрабатываются иерархические структуры (папки) в результате в список попадают не все подключенные базы.

    В список включаются базы SQL, а обработка таких баз не предусмотрена.

    Жаль что нет комментарием по тексту модуля формы.

    Модуль обработки не смотрел — пароль…

    Reply
  4. gnataly

    Да, базы SQL попадают — будет время отфильтрую. Писалось, как всегда, в запале

    работы, как оперативное решение. У клиентов, где SQL там бэкапят средствами СУБД.

    А про папки не замечала, все работает независимо от групп. Для проверки все демо базы перенесла в группу демо — список баз заполнился.

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

    В модуле обработки всего лишь получение системной папки, где хранятся списки баз.

    Будет интерес — открою… Скачивания есть, а оценок нет. Пока непонятно насколько нужная вещь, просто возникло желание поделиться. До этого времени регулярно посещала сайт и подчерпнула много полезного. Обмен разработками намного упрощает нашу работу. Подумаещь о чем-то, а кто-то уже написал и предоставил доступ в общее пользование. Вот что значит «сила мысли».

    Новые идеи и замечания приветствуются!

    Reply
  5. alexk-is

    «В модуле обработки всего лишь получение системной папки» через переменную среды %APPDATA% ? 🙂

    «Список баз заполнился». Да, но некоторые базы почему-то не попали в список. У меня в файле ibases.v8i более 500 строк…

    Reply
  6. gnataly

    (5) 1. нет, через «MSScriptControl» 🙂 — от профессионалов не закрыться, пароль для

    того, что-бы творческие личности случайно не попортили обработку

    (распространялось среди неподготовленных, но очень любобытных пользователей).

    2. Мдя.., у меня 461 строка. Все, что нужно, вроде вижу, более детально могу рассмотреть чуть позже. Сейчас срочное задание по работе.

    Reply
  7. gnataly

    (5) Что-то вдруг осенило — может, сортировка по алфавиту в заполненном табличном поле поможет?

    Reply
  8. alexk-is

    (7) Нет. Я хорошо проверял. Соответственно сортировал и по наименованию, и по каталогу. Может проблема в том, что у меня много ссылок как в каталогах так и без них…

    Исправил +5 и +7 на +1. Первоначальный список из 40 баз увеличился до 63. 🙂

    Код
       Для НомерСтроки = 1 По КолСтрок Цикл
          Стр2 = Текст.ПолучитьСтроку(НомерСтроки);
          Если Лев(СокрЛ(Стр2),7) <> "Connect" Тогда
             Стр1 = Стр2;
             Продолжить;
          КонецЕсли;   
          Имя = Сред(СокрЛП(Стр1),2,СтрДлина(СокрЛП(Стр1))-2);
          Позиция1 = Найти(Стр2,"""");
          Стр2 = Сред(СокрЛП(Стр2),Позиция1+1,СтрДлина(СокрЛП(Стр2))-(Позиция1+2));
          Путь = Стр2;
          НоваяСтрока = Тз.Добавить();
          НоваяСтрока.Сохранение = Истина;
          НоваяСтрока.ИБ = Имя;
          НоваяСтрока.Путь = Путь;
       КонецЦикла;
    

    Показать полностью

    Reply
  9. rasswet

    я юзаю Эффектор: Сэйвер. бесплатная прога, архивирует штатными средствами (и по-моему может тупо в архив)

    раньше батники писал и вешал их в планировщик, теперь вот ней. вполне устраивает. всё что нужно есть и ничего лишнего.

    это не реклама, сам вычитал где-то, попробовал-понравилось:)

    Reply
  10. gnataly

    (8) Вы правы, «+1» считывает список полностью. Обработку обновила, заполнение списка баз проверила — в файле и в таблице количество совпадет.

    Добавила фильтр по серверным базам.

    Reply
  11. dance000

    (9) у эффектора наблюдалась проблема он периодически вылетал, притом у разных клиентов. пришлось отказаться

    Reply
  12. barnik

    нужная вещь, особенно когда у клиентов и надо сделать копию базы простой архивацией каталога!

    Reply
  13. lepth

    эффектор не бэкапит базы больше 2Гб

    Reply

Leave a Comment

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