<?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='\
(0)
А не пробовали сделать диапазон от 1 до 1 000 000, а затем получить остаток от деления от 100? по природе генераторов случайных чисел это должно вам помочь
Молодец, давно тебе говорил: опубликуй эту идею
(0)
Практические испытания (10 000 полученных значений) показывают то, что штатный генератор распределяет значения куда лучше, чем ваша реализация основанная на UUID.
см. во вложении диаграмму.
Верхняя диаграмма использует:
Нижняя диаграмма использует:
Обратите внимание на нижней диаграмме граничные значения (0 и 99). Тут ваш алгоритм вообще плохо себя ведет. Я уже не говорю о том что использование UUID получается на порядки медленней.
Может потому что в одну секунду их генерировал? На сколько помню генератор завязан на системное время.
Посмотрите тутhttps://habrahabr.ru/post/132217/ начиная с текста «Получение псевдослучайных чисел на основе полиномиального счетчика», возможно этот метод тоже подойдет.
(3) У меня дополнительные требования были к генератору, кроме нормального распределения, должно быть еще, что бы в один момент времени не было повторяющихся номеров, это выявится если ГСЧ.СлучайноеЧисло(0,99) запустить в несколько потоков.
(1)Не помогала, даже более того, что любая функциональная зависимость, основанная на арифметических операциях, при одинаковых входных данных дает одинаковые выходные, поэтому понадобилось что то похитрее.
(2)Да случайно у себя на неё наткнулся, подумал, пора)
(6)
так вы попробуйте при создании генератора инициализировать его случайным образом (идентификатор сеанса например)
Зачем после возврата из рекурсивного вызова (Уник = ПолучитьСлучайноеЧисло(Мин, Макс);) опять приводится к интревалу?
Сразу его вернуть нельзя «Возврат ПолучитьСлучайноеЧисло(Мин, Макс);» ?
(10)Чтобы избежать случая, где GUID будет состоять из недостаточного количества цифр (составляющие GUID будут больше 9), в данном случае это не произойдет, но если этот генератор нужен будет для использования с длинной числа > 16 то лучше сделать эту проверку.
ЭЭЭЭ…. А на фига все это ? Я тоже общаюсь с wms, и мне хватает префиксов в номерах документов, чтобы получить уникальный номер Ж)
А глобальная статическая переменная не выход?Пожалуй, не выход.(12) Согласен что нумератор надо использовать из документа. Такое вот наследство было, и хорошо что вообще не в константе не хранили, а переделывать нельзя было, во первых, ответственная часть, во-вторых, этот элемент использовался в интеграции с другими системами. Если что то не так пойдет то много процессов бы встало, а так если отделаться малой кровью и избавиться от проблемы блокировки, использовалось такое решение.
Я бы попробовал хранить счетчик(и) во внешней базе MS SQL, используя хранимую функцию, возвращающую и автоинкрементирующую нужный счетчик в момент обращения.
(15)Проверял разные готовые генераторы, в том числе и виндовые, они не дают нужную последовательность случайных чисел, и скорее всего скуль тоже использует те же генераторы, если оно так, то такая автоинкрементация будет давать в один момент времени один и тот же счетчик, да и с внешней базой тоже вопрос, получается такая мелкая, но очень важная база, про которую скорее всего все забудут, и в какой нибудь момент когда что нибудь накроется или переедет, могут быть проблемы.
(11)
Зачем нужен рекурсивный вызов — понятно. (для перегенерации случ.числа при получении гуид с малым количеством цифр)
Не понял зачем полученный из рекурсии результат опять приводится к интервалу. Ведь он и так должен вернуться в нужном диапазоне.
Интересно, если использовать все цифры гуида распределение ухудшается или нет?
Взято тут:http://www.forum.mista.ru/topic.php?id=196865
Не проверял
В конце:
Показать
Чисто академический интерес — Новый УникальныйИдентификатор несёт в себе дату-время как вhttps://helpf.pro/faq/view/1099.html ?
Код 1C v 8.
Показать
Отсюда же я взял преобразование из 16-ричной системы, только слегка упростил формулу.
(20) Проверил. Нет. Не несет.
(18)Давно конечно эксперементировал, но все эти генераторы давали достаточно хорошее «нормальное» распределение, если не брать создание в 1 момент времени, да и с 16-ричными числами в 1с работать как то не удобно.
(21)Вроде он должен нести в себе дату время + счетчик. Может только в какой нибудь другой зависимости.