Генератор случайных чисел/символов




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

5 Comments

  1. Pasha1st

    Почему-то многие забывают о такой вещи, что если строка предназначена для человека (это генератор паролей, например), то не стоит допускать одновременного появления в пароле визуально схожих символов — 0 и O, 1, l и I. Их требуется или полностью исключить, или оставить только какой-то однозначный вариант, например только цифры. А ещё можно сделать управление вероятностью появления символа из конкретного набора (больше-меньше цифр).

    Reply
  2. okabysh

    (1) Pasha1st,

    Приветствую, Павел.

    Спасибо за комментарий.

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

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

    Reply
  3. Alias

    (2) «Для меня уникальность значений очень критична, поэтому я сохраняю все сгенерированные случайные числа в регистр сведений»

    А если не секрет, почему именно такой, не самый оптимальный с моей точки зрения, путь выбран? Это же хранить все выданные последовательности, да ещё и постоянно проверять уникальность…

    Скажите, разве не проще было сделать самый обычный инкрементальный счётчик, хоть в той же константе? Никаких регистров, никаких проверок… Сплошные плюсы! Знай себе +1 делай и всё.

    А если очень хочется иметь именно 6-тисимвольный код, можно преобразовать значение полученного счётчика в символьную последовательность, — алгоритм абсолютно аналогичен переводу в другую систему счисления. Бонусом имеем ещё и отслеживаемую хронологию…

    М-м?

    Reply
  4. okabysh

    (3) Александр, спасибо за комментарий.

    ответ на: «А если не секрет, почему именно такой, не самый оптимальный с моей точки зрения, путь выбран? Это же хранить все выданные последовательности, да ещё и постоянно проверять уникальность…».

    Дело в том, что мне нужно знать, какому объекту я выдал в моем случае 6-ти значный код, поэтому я храню данные в регистре по 2-м измерениям: ссылку на объект и 6-ти значный код с типом «Строка». Когда потребуется найти объект, я его всегда найду, зная 6ть символов кода. В моем случае требовалось использовать минимум символов для кодирования, но чтобы их было нельзя подобрать, поэтому я не мог брать простой счетчик, к примеру, от 100000 + 1, +1, +1 …

    Еще можно использовать GUID, тогда уникальность практически на 100% гарантируется, но коду требуется уже 36 символов. Повторюсь, в моей ситуации 36 символов это много и следовательно не подходит. Поэтому я сделал, как сделал)

    Основная цель публикации:

    показать на «пальцах» как использовать ГенераторСлучайныхЧисел() и его особенность.

    Так что пусть каждый реализует свою логику как считает нужным.

    Reply
  5. Alias

    (4) Ясно, спасибо за уточнение. «…Чтобы их было нельзя подобрать…» — это ключевая фраза. Да, в таком случае автоинкрементируемый счётчик не очень подходит — он слишком легко прогнозируем (что в других случаях могло бы быть плюсом).

    Reply

Leave a Comment

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