Комментарии. Какие и зачем?




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

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

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

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

31 Comments

  1. dalgaso2010

    Если говорить о комментариях для описания функций, то я уже давно пришел в стилю jsDoc. Например

    //**
    //* Это супер функция, которая делает, что-то
    //* важное.
    //*
    //* @param {Число} Параметр1
    //* @param {СправочникСсылка.Контрагенты} Контрагент
    //* @return {Массив.<СправочникСсылка.Номенклатура>}
    Функция МояСуперФункция (Параметр1, Контрагент)
    //TODO написать код функции
    КонецФункции
    

    Показать

    Плюсы от такого стиля очевидны: компактность, стандартизация. Последний пункт позволяет без проблем задокументировать код и создать какой-нибудь симпатичный документ. Что касается комментариев к отдельным строкам кода, то тут лично у меня прижился уже классический вариант:

    //АИВ 01.01.01  Комментарий / 

    Или многострочный вариант

    //АИВ 01.01.01 \r
    //Комментарий
    //АИВ 01.01.01 /
    Reply ↓
  2. vcv

    Многое зависит от назначения комментария. Комментарии в стиле jsDoc, помянутые в (1) полезны. Позволяют автоматически формировать документацию и понимать смысл параметров, не анализируя код.

    А вот комментарии в виде

    //АИВ 01.01.01 \r

    //Комментарий

    //АИВ 01.01.01 /

    или

    Во всех местах, где вносятся изменения, в комментариях указывается данный идентификатор.

    сильно спорны. Главная их проблема в том, что их актуальность нужно поддерживать. Вот, представьте, что для техзадания ТЗ01_НДС вы изменили строки 100-110 и отметили их комментарием. Потом, через годик, по техзаданию Т515_НДС вы в этом же модуле изменяли строки 80-120. Куда вы денете комментарий ТЗ01_НДС и какова будет его актуальность?

    Для часто дописываемых проектов лучше использовать какой-нибудь git. Что бы всё было чётко: есть коммит, есть назначение коммита, есть внесенные им изменения.

    Reply ↓
  3. kraynev-navi
    Вот, представьте, что для техзадания ТЗ01_НДС вы изменили строки 100-110 и отметили их комментарием. Потом, через годик, по техзаданию Т515_НДС вы в этом же модуле изменяли строки 80-120. Куда вы денете комментарий ТЗ01_НДС и какова будет его актуальность?

    А что мешает переделать строки 100-110 в рамках проекта по изменению 80-120?

    Т.е.

    //Т515_НДС (
    //Комментарий
    ..
    //ТЗ01_НДС (
    //Комментарий поясняющий изменения в связи с новой заявкой Т515_НДС
    // ) ТЗ01_НДС
    …
    // ) Т515_НДС
    

    Показать

    Reply ↓
  4. mrXoxot

    (1) dalgaso2010,

    Да, с описание параметров действительно получаются отличные комментарии. К тому же текущая версия платформы позволяет такие комментарии использовать в синтаксис-помощнике. Например как на приложенном скриншоте.

    Reply ↓
  5. mrXoxot

    (2) vcv,

    Главная их проблема в том, что их актуальность нужно поддерживать.

    Это действительно так. Но вообще и актуальность кода лучше поддерживать.

    Для часто дописываемых проектов лучше использовать какой-нибудь git. Что бы всё было чётко: есть коммит, есть назначение коммита, есть внесенные им изменения.

    Ну для этого ждем EDT, кажется там уже это будет поддерживаться в полном объеме.

    Reply ↓
  6. JesteR

    В свои комментарии добавляю номер задачи. Задач бывает несколько и довольно долгих по времени.

    Поэтому использую шаблон 1С, пример:

    //{MyLogin (<?»НомерЗадачи», ВыборВарианта,
    «Резервы», «105»,
    «Доработкая для буха», «102»,
    «Без номера», «»>) <?»», ДатаВремя, «ДФ=yyyy.MM.dd»>
    <?>
    //MyLogin (<?»НомерЗадачи», ВыборВарианта>) <?»», ДатаВремя, «ДФ=yyyy.MM.dd»> }
    
    Reply ↓
  7. mrXoxot

    (6) JesteR,

    А вот это действительно здорово. Спасибо!

    Reply ↓
  8. vcv

    (3) kraynev-navi,

    А что мешает переделать строки 100-110 в рамках проекта по изменению 80-120?

    Да, переделаете. Но что делать с комментарием? На сколько этот комментарий будет соответствовать результирующему коду? Особенно если его (этот комментарий и прошлое изменение) писали не вы.

    Обычное же дело. Сначала изменили строки 100-110. Потом, по другому заданию, 90-110. Потом 80-100. Потом переписалось все с 50 по 150.

    Куда и как девать старые комментарии?

    Это действительно так. Но вообще и актуальность кода лучше поддерживать.

    Но ведь гораздо проще и экономически эффективней просто писать хороший читабельный код, чем писать хороший код, к нему хорошие комментарии и поддерживать соответствие кода и комментариев.

    Reply ↓
  9. mrXoxot

    (8) vcv,

    Сначала изменили строки 100-110. Потом, по другому заданию, 90-110. Потом 80-100. Потом переписалось все с 50 по 150

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

    Если потребовалось переписать все с 50 по 100, тогда это уже будет новая задача, которая исключает предыдущие.

    Но ведь гораздо проще и экономически эффективней просто писать хороший читабельный код, чем писать хороший код, к нему хорошие комментарии и поддерживать соответствие кода и комментариев.

    Абсолютно полностью поддерживаю! Лучше писать хороший читабельный код, это факт. Но, к сожалению, не всегда это удается и тогда на выручку приходят комментарии.

    Reply ↓
  10. klinval

    (0) В 3-м пункте вы написали:

    Процедура Infostart_НоваяПроцедура(Параметр1)
    
    Параметр1 = Параметр1 + 1
    
    КонецПроцедуры

    А вы эту процедуру поместите в конце модуля? Просто тогда раздел основной программы будет различаться из-за #КонецОбласти….

    Есть второй вариант: поместить перед разделом основной программы, но тогда будет так что, например, в область «Печать» попадёт какая-нибудь процедура «ПриИзменениЧегоЛибо».

    Reply ↓
  11. vcv

    (10) klinval,

    Вот кстати, не касательно пункта 3, а касательно приведенной процедуры.

    Процедура Infostart_НоваяПроцедура(Параметр1)
    
    Параметр1 = Параметр1 + 1
    
    КонецПроцедуры

    Чем подобных процедур меньше, тем лучше. Неявная модификация переданного в процедуру параметра — зло.

    Reply ↓
  12. dalgaso2010

    (2) vcv,

    Тут еще все зависит от проекта. Мне не очень нравится хранить историю комментариев, ибо потом в коде трудно ориентироваться. Для детального описания изменений есть трекер. В принципе, отследить что менялось можно истории задач. Ну а если прям нужны детали до «строчки», то тут без GIT не обойтись.

    Reply ↓
  13. o.nikolaev

    >> Процедура Infostart_НоваяПроцедура(Параметр1)

    >> Параметр1 = Параметр1 + 1

    >> КонецПроцедуры

    Не использую такой подход. Только хранилище и внешние СКВ (системы контроля версий).

    Автор, без обид, прочитайте волшебную книжку «Совершенный код» Стива Макконнелла, там все написано по этой теме. При доработках типовых включаю хранилище и все доработки делаю через него. В комментарии к версии указываю и номер задачи и описание изменений. В том случае, если работа с клиентом заканчивается, передаю ему и хранилище и базу задач. В базе задач хранится все — кто, что, когда, зачем, файлы и т.п. (последователю понадобится и пригодится).

    Для внешних обработок использую Tortosie.

    Reply ↓
  14. orefkov

    Имхо, все эти комментарии о вносимых изменениях — от безысходности и отсутствия нормальной системы управления версиями.

    Началось ещё с семёрки, да так и прижилось.

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

    Кому нужна история — пусть копаются в летописях. Так вот в 1С — нет удобной системы их писания и копания, поэтому летописи перекочёвывают в код, превращая его в «преданья старины глубокой». На кой, извините ляд, мне знать, что три года назад тут был Вася и убрал то, что пять лет назад вписал Петя?

    Reply ↓
  15. artbear

    (0) и другие: «Авторские» комментарии — зло, как уже написали несколько человек.

    Представляете, какой у вас будет код через несколько лет? немного реального кода и куча комментариев «тогда-то здесь отметился Вася по такой-то нужде» 🙂

    Git (blame), системы код-ревью рулят.

    Используйте фоновую выгрузку из 1С в Git, например, наш бесплатный открытый проект gitsync

    и уже в Гите смотрите историю, кто и что, когда и почему менял.

    Reply ↓
  16. V.Nikonov

    По моему у комментариев есть несколько целевых задач:

    1. Объяснить ход выполнения функционала, уточнить логику решения и т.п. (Это самое важное! Без этого затруднена отладка и модификация программы.)

    2. Задокументировать отличия от типового решения. (Такие комментарии должны облегчать обновления типового продукта. В т.ч. содержат описания кода, который необходимо сохранить при обновлениях)

    3. Протоколировать решение дополнительных прикладных задач. (Подразумевается наличие документации в виде проработанного ТЗ на доработку)

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

    Кроме того, в ходе написания актуальных комментариев, желательно подчищать комментарии оставленные «предками». Особенно, если предыдущие доработки теряют актуальность. Например, хранить сведения, что некий коэффициент в 2010 году был 1.5, в 2012 стал 1.6, а с 2015 года равен 1.65 — вероятно не следует. Комментарий должен служить сегодняшнему и завтрашнему дню!

    Reply ↓
  17. NazarovV

    Мы вот так комментируем)

    //Заявка №000002911 Назаров В.Г. 18 ноября 2015 г. {{

    //Заявка №000002911 Назаров В.Г. 18 ноября 2015 г. }}

    Формируется автоматически в буфер из базы заявок…

    Если мы комментируем чужой код или типовой есть несколько вариантов:

    Если код типовой — комментируем всегда;

    Если код не типовой, в нем ошибка или понимаем что логика устарела — удаляем и пишем свое.

    Если код не типовой и возможно, что в будущем возможно возвращение к нему — комментим и внизу пишем свое.

    Reply ↓
  18. vcv

    (14) orefkov,

    На кой, извините ляд, мне знать, что три года назад тут был Вася и убрал то, что пять лет назад вписал Петя?

    В таком виде не нужно. А вот понять, зачем кто-то или ты сам вставил или закомментарил определенные строки, может быть полезно. Потому что бывают тонкости, о которых сразу не сообразишь, которые вылазят раз в месяц на определенном документе…

    (15) artbear, Git и прочее рулит, но прилично написанные комментарии в коде ценны, когда ты пробегом у клиента несколько раз в году. Всему своё место. Для фикси требуется толковая система типа git, на аутсорсинге хорошо бы толковый комментарий оставить себе или другому аутсорсеру.

    Reply ↓
  19. mrXoxot

    (13) o.nikolaev,

    Расскажите, пожалуйста, подробнее про Tortosie — а то гугл выдает, что это тяжелый штурмовой танк.

    (16) V.Nikonov,

    2. Задокументировать отличия от типового решения. (Такие комментарии должны облегчать обновления типового продукта. В т.ч. содержат описания кода, который необходимо сохранить при обновлениях)

    Здесь не совсем согласен. Отличия от типового решения прекрасно видны при сравнении и объединении, гораздо важнее объяснить почему здесь не устраивает типовая логика.

    (18) vcv,

    Git и прочее рулит, но прилично написанные комментарии в коде ценны, когда ты пробегом у клиента несколько раз в году. Всему своё место. Для фикси требуется толковая система типа git, на аутсорсинге хорошо бы толковый комментарий оставить себе или другому аутсорсеру

    Да, если это изменения у обычного клиента с мелкой доработкой, то использовать Git для этой доработки, кажется, излишним.

    Reply ↓
  20. v.yaunzhekars@gmail.com

    Насколько я понял автора, комментарии вида «ТЗ01_НДС» предлагается использовать для связи с проектной документацией, и это полезно.

    Позволяет узнать, зачем здесь этот код.

    На мой взгляд

      Комментарии, поясняющие алгоритм или тонкости реализации в коде не нужны. Лучше писать понятный код. Если код нуждается в комментарии, то он также нуждается и в рефакторинге.

      Исторические комментарии вида «//AKA Vasili 31.11.2014», тоже бесполезны. Что даст информация о том, когда и кем добавлен код? Код не для этого. Для того чтобы узнать, кто и когда вносил изменения, лучше пользоваться хранилищем

      Комментарии призванные отличить типовой код от доработанного. Лучше что бы их тоже не было. Вставку на вызов собственной функции в собственном модуле можно отличить и без комментариев. А вставки целых алгоритмов в типовой код больше напоминают костыли, и им, конечно же, нужны комментарии. Если что то добавляешь, то лучше это реализовать в отдельных объектах и модулях. А если просто подправляешь типовой алгоритм по месту, то смирись с тем что это костыль, и напиши комментарий.

    Reply ↓
  21. o.nikolaev

    (19) http://tortoisesvn.net, тут все написано.

    Reply ↓
  22. o.nikolaev

    (18) vcv,

    Потому что бывают тонкости, о которых сразу не сообразишь, которые вылазят раз в месяц на определенном документе…

    Это значит что код написано неясно. Соблазн подобного рода, за счет комментариев попытаться сгладить кривизну решения, велик, и грешат им, чоуш. Но это неправильно. Опять же, повторюсь, у Макконнела про все это написано более подробно и убедительно.

    Reply ↓
  23. softcreator

    Я извиняюсь, а чем вам хранилище конфигурации не подходит?

    Отправляем в него ту же типовую при создании хранилища, а затем пилим ее как нужно нам или заказчику. Преимущества: быстрый откат и возможность сравнения версий.

    Reply ↓
  24. klinval

    (20) Vova1900,

    Комментарии, поясняющие алгоритм или тонкости реализации в коде не нужны. Лучше писать понятный код. Если код нуждается в комментарии, то он также нуждается и в рефакторинге.

    Я смотрю вы идеалист. Если вы пишите код на 1000+ строк и он без единого комментария понятен любому — то я вам завидую.

    Исторические комментарии вида «//AKA Vasili 31.11.2014», тоже бесполезны.

    У нас исторические комментарии совмещены с описанием и номером заявки. Т.е. коммент вида:

    //<Определенный наш уникальный открывающий комментарий из 4 символов> Фамилия Дата КраткоеОписание (номер заявки в нашей IT системе)

    Закрывающий коммент такой-же только маленько другой уникальный закрывающий тег. Т.е. мы сразу открывая модуль можем найти поиском все наши изменения. Видим кто, когда и зачем внёс. Если что-то непонятно есть номер заявки и по нему можно найти подробную информацию.

    Что даст информация о том, когда и кем добавлен код? Код не для этого. Для того чтобы узнать, кто и когда вносил изменения, лучше пользоваться хранилищем

    А если в модуль вносил изменения более 1 человека более 10 раз. Что вы увидите в хранилище: Иванов когда-то что-то внёс, Петров и Сидоров. А кто конкретный код внёс непонятно, надо тратить много времени на анализ хранилища. Хранилище 1с в этом плане недостаёт функционала.

    А сама по себе быстрая информация кто внёс даёт возможность найти человека которого можно спросить какие-либо нюансы реализации (вместо курения кода) или можно ему перекинуть свою задачу, раз он всё-равно в курсе. Дата даёт возможность быстро понять когда этот механизм был внедрён и заработал.

    Reply ↓
  25. Pover

    К счастью на комментарии не распространяются жесткие правила. Это что то типа стиля программиста. У каждого он свой.

    Полезно для посмотреть а как у «АКА Васи»

    Reply ↓
  26. fomix

    (23) softcreator, Хе-хе, а если Хранилище наипнется, что тогда делать будем, а?! Или место в старом закончится и придется новое делать, а?!

    Reply ↓
  27. vcv

    (22) o.nikolaev,

    Это значит что код написано неясно. Соблазн подобного рода, за счет комментариев попытаться сгладить кривизну решения, велик, и грешат им, чоуш. Но это неправильно.

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

    Reply ↓
  28. Bassgood

    (0) По пункту три — с версии 8.3.5, на сколько помню, для обрамления новых процедур вместо комментов можно использовать области #, выглядят они куда более симпатичнее.

    Reply ↓
  29. mrXoxot

    (28) Bassgood,

    Да, но проблема осталась та же. #КонецОбласти будет отображаться в сравнении и объединении. Поэтому либо не ставить такие процедуры в конец, либо не ставить такие области.

    Reply ↓
  30. Bassgood

    (29) а что мешает ставить их в начало модуля, чтобы было сразу видно какие процедуры свои мы туда напичкали?

    Reply ↓
  31. klinval

    (30) Bassgood, как вариант, но если мы обрамляем свои процедуры комментариями или #Областями то последний комментарий или #КонецОбласти попадёт в типовом сравнении к первой типовой процедуре (см. приложение).

    Reply ↓

Leave a Comment

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