ООП. Инкапсуляция. Часть 1.




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2025-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='\

24 Comments

  1. tango

    В типовой (УПП?) что-то похожее встречалось, да.

    «Инкапсуляция на последней миле»

    Скоро план счетов вообще станет не регистром учета, а чисто жупелом.

    Reply
  2. Fuego

    (1) А когда план счетов был регистром учёта?..

    Reply
  3. coder1cv8

    Это чего? Семерошники таким извратом вместо предопределенных занимаются?… )

    Reply
  4. tango

    (4) ?

    вот «васмерашники» (упп):

    Сч62_01 = ПланыСчетов.Хозрасчетный.НайтиПоКоду(«62.01»);

    Сч62_21 = ПланыСчетов.Хозрасчетный.НайтиПоКоду(«62.21»);

    Сч62_31 = ПланыСчетов.Хозрасчетный.НайтиПоКоду(«62.31»);

    Сч90 = ПланыСчетов.Хозрасчетный.НайтиПоКоду(«90»);

    Сч62_02 = ПланыСчетов.Хозрасчетный.НайтиПоКоду(«62.02»);

    Сч62_22 = ПланыСчетов.Хозрасчетный.НайтиПоКоду(«62.22»);

    Сч62_32 = ПланыСчетов.Хозрасчетный.НайтиПоКоду(«62.32»);

    Сч86 = ПланыСчетов.Хозрасчетный.НайтиПоКоду(«86»);

    Сч58_03 = ПланыСчетов.Хозрасчетный.НайтиПоКоду(«58.03»);

    Сч60_02 = ПланыСчетов.Хозрасчетный.НайтиПоКоду(«60.02»);

    Сч60_22 = ПланыСчетов.Хозрасчетный.НайтиПоКоду(«60.22»);

    Сч60_32 = ПланыСчетов.Хозрасчетный.НайтиПоКоду(«60.32»);

    Сч91_01 = ПланыСчетов.Хозрасчетный.НайтиПоКоду(«91.01»);

    Reply
  5. tango

    а вот еще прикольней, из той же УПП:

    СчетКоррБУ = ПланыСчетов.Хозрасчетный.НайтиПоКоду(КодСчетаКоррБУ);

    Reply
  6. artbear

    (0) Федор, в первой же строке баг 🙂

    «Обектный подход к программированию» 🙂

    А вообще плюс, без вопросов.

    Reply
  7. vde69

    вообще это не «Инкапсуляция» а «модульность»

    Инкапсуляция — свойство языка программирования, позволяющее объединить данные и код в объект и скрыть реализацию объекта от пользователя. При этом пользователю предоставляется только спецификация (интерфейс) объекта.

    то-есть это закрытие данных обьекта за програмную оболочку, то-есть запрет прямого обращения к полям!!! в семерке нельзя закрыть доступ к полям данных, по сколько нету разделения на области видимости.

    Reply
  8. tango

    А модульность («вся система должна быть разделена на части, называемые модулями. Это деление более крупное, чем разбиение на классы — модули должны их в себе содержать») тут в чем?

    Reply
  9. O-Planet

    Статью — ф топку, или переименовать, или привести другой пример. то, что сейчас, к инкапсуляции имеет очень сомнительное отношение. Инкапсуляция — это объединение данных с методами их обработки. Приведенный в статье пример можно — не в тему. Можно вообще использовать глобальную переменную: глСчетРеализации. По идее статьи это тоже будет инкапсуляция.

    Reply
  10. fez

    (7) Спасибо, Артур. На домашней клавиатуре твердый знак плохо нажимается 🙂

    Reply
  11. fez

    (8) А никто и не говорит, что семерка — это объектно-ориентированный язык программирования. Но если понимать, зачем это нужно — можно ведь и не обращаться к полям данных самостоятельно. Усилием воли. Несмотря на то, что язык позволяет это делать.

    Reply
  12. fez

    (10) Согласен. глСчетРеализации — это тоже инкапсуляция. Дело в том, что инкапсуляция сама по себе не является отличительной чертой только и исключительно объектно-ориентированных языков программирования. Это некоторый прием програмирования, который позволяет решать определенные задачи. Объектно-ориентированные языки всего лишь активно поддерживают инкапсуляцию своим синтаксисом.

    Reply
  13. fez

    (4) Нельзя ли поподробнее про предопределенные? В восьмерке я не очень, так что с интересом послушаю.

    Reply
  14. coder1cv8

    (14) предопределенные элементы — это элементы созданные на этапе конфигурирования, для которых задано имя и к которым по этому имени можно обращаться из кода, например: ПланыСчетов.Хозрасчетный.СчетРеализации

    Таким образом, изменение кода элемента не влияет на логику работы конфигурации.

    (5) Не знаю чего уж там в УПП, но обычно так не делают…

    Reply
  15. fez

    (15) Ага, понятно. Завтра будет часть вторая, где я постараюсь рассказать, чем может оказаться плох и такой подход тоже (на примере констант 7.7).

    Reply
  16. vde69

    (16) если уж и обсуждать эту тему, то только в разрезе восьмерке, там реализация будет такая:

    обьект конфигурации (например константа ДополнительныйПароль) для пользователя запрещаем чтение и запись, но в привелегированом модуле описываем процедуры

    ПроверкаПароля

    СменаПароля

    при этом проверка и смена могут внутри себя вычислять хеш и хранить уже его и в добавок выполнять еще действия (например писать лог)

    Вот это будет уже ближе к САБЖУ, но все равно это НЕ Инкапсулирование

    Reply
  17. O-Planet

    Инкапсуляцию в 1С можно увидеть, рассматривая встроенные объекты, такие, как Справочник, Документ. С документом можно работать, как с единицей информации, но в своей структуре он имеет параметры (поля) и функции.

    Reply
  18. ineoosaki

    Еще, над этим подискутируйте:

    http://stupid1snik.narod.ru/

    В статье, автор, о наследовании (приминительно к 1с) рассуждает.

    Reply
  19. artbear

    (18) (10) Нет, ты не совсем прав 🙁

    ИМХО в инкапсуляции главное это как раз сокрытие реализации от клиента, а уж объединение данных и кода это вторично 🙂

    Например, можно представить класс, в котором нет данных, а только спрятанные методы и открытый интерфейс.

    Reply
  20. artbear

    (0) Ссылка на вторую часть статьи желательно бы к этой статье приложить 🙂

    ЗЫ ну и наоборот, конечно.

    Reply
  21. Ёпрст

    2-ая часть

    http://infostart.ru/blogs/886/

    Reply
  22. BabySG

    (21) Смешная статья 🙂

    То, что там написано реализуется через Подписки на события.

    И автор не учитывает, что очень часто требуется изменить саму логику проведения и придется ПОЛНОСТЬЮ переписать процедуру проведения.

    Вот на этом обычно и спотыкается ООП в 1С.

    Наследование от документа «Инвентаризация» что может дать, за исключением геморроя в регистрах и прочего?

    ЗЫ. Что бы не было воплей — занимался несколько лет системным программированием на С++ — так что ООП знаю не по наслышке.

    Reply
  23. O-Planet

    (22) Этимологически, инкапсуляция — это сокрытие. Второе значение — согласование. В применении к программированию термин инкапсуляция используется во втором значении. Иначе, чем инкапсуляция отличается от процедурности и той же параметризации? Вообще, всю программу можно представить в виде одной универсальной процедуры с входными параметрами. Собственно, на С так и есть. Но сказать, что мы инкапсулируем программу в функцию main будет неправильно. А вот сказать, что методы инкапсулируются в класс — звучит верно.

    Reply

Leave a Comment

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