<?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='\
и зачем это, два раза прочитал не понял
Очень ценная информация. Жаль раньше сам не додумался :))
Что-то есть подозрение, что переменная будет жить 20 минут (а может даже и всего 5)
(3) да, конечно. Если сеанс будет жить 20 минут (или всего 5)
Сохранение соответствия «ключевые параметры»->»возвращаемое значение» и возможность обращения к нему — это конечно корошо и не только для возврата соответствия, как в примере (вызов непараметризируемой функции), т.к. здесь придется еще позиционироваться на элементе соответствия. Если параметр у функции один — строка — идентификатор переменной, то и получается нечто вроде функции возвращавшей значение параметра сенса в 8.1. А можно и многомерить (составной ключ — значение)
Остается вопрос — сколько вот таких запоминаний может быть в рамках сеанса, и будет ли все это корошо чиститься по завершении сеанса. 😉
Я бы еще заголовок темы поменял. Ну как-то не совсем он коррелирует с описанием. Например, из первого предложения темы — «Реализация глобальных переменных и обращение к ним на сервере 8.2». 😀
(5) данный пример максимально наглядно показывает, что возможно сохранение ссылки на объект. Что за объект — это уже не важно.
Количество сохраняемых объектов платформа не ограничивает.
Чиститься будет, если не будет циклических ссылок
(6) как говорила наша химичка, что пнем по сове, что совой об пень…
(7) Я бы сказал, что данный пример показывает возможность сохранения соответствия в рамках сеанса и обращения к нему в первую очередь. А что запихано в соответствие — да что угодно, благо там нет ограничения на типы хранимых в соотв. объектов. 😉
(9) почему соответствие? это может быть структура, ТЗ, ВК, …
смысл в том, что хранится именно ссылка, а не копия объекта
(10) в примере то именно соответствие 🙂 Для меня соответствие — это не ссылка. Это агрегатный объект/тип:) А хранить наверное можно все, что может возвращать подобная функция с указанными свойствами, либо агрегатный объект/тип, ею возващаемый.
(11) соответствие для демонстрации выбрано только потому, что в нем проще хранить уникальные значения (дату).
А агрегантный объект может быть либо ссылкой (как в данном примере) либо копией (в типовых 8.1 можно посмотреть функцию глПолучитьЗначениеПеременной(…) — название может быть несколько не такое)
(12) Вот и замечательно. В статье отражены и другие аспекты демо-примера 🙂
Плюсанул, ком объекты, кстати тоже кешируются.
(14) см. (10)
Может пригодится.
Плюсанул.
ИМХО в 8.2 в данном вопросе как-то все очень извращенно получилось 🙁
Спасибо, помогло! Плюсанул.
расскажите на примере, плиз, зачем это нужно?
(19) не надо придумывать задачу по возможностям, надо искать возможности для решения задач
СУПЕР — это то что я долго искал, большое спасибо
Если быть еще более точным, то читать надо не реже чем каждые 6 минут и даже в этом случае через 20 минут после вычислени все равно «умрет». А может и раньше если не повезет и серверу станет мало памяти.
Возможность очень интересная, но очень неуниверсальная 🙁 т.к. нет возможности явно управлять временем жизни кеша.
(22) да, да, да.
на момент публикации еще небыло столь подробных комментариев от 1С, а сечас уже есть. и в связи с этим данный механизм уже не столь красив как казалось.
Очень интересно. Спасибо
Наткнулся на публикацию, а чем параметры сеанса в качестве глобальных переменных хуже?
Спасибо! Отлично работает.
http://infostart.ru/public/62410/ , выдаёт ошибку «Переданное значение не может быть помещено во временное хранилище».
Внимание! В 8.3 не работает способ с использованием ПараметрСеанса, описанный тут:
Из документации:
Сохраненные значения удаляются:
Если свойство установлено в значение На время вызова:
● на стороне сервера – при возврате управления с сервера;
● на стороне клиента – при завершении работы процедуры или функции встроенного языка верхнего уровня (вызванной системой из интерфейса, а не из другой процедуры или функции встроенного языка);
Если свойство общего модуля установлено в значение На время сеанса:
● на стороне сервера – при окончании сеанса;
● на стороне клиента – при закрытии клиентского приложения.
Сохраненные значения будут удалены:
● на сервере, в толстом клиенте, во внешнем соединении, в тонком клиенте и в веб-клиенте с обычной скоростью соединения – через 20 минут после вычисления сохраняемого значения или через 6 минут после последнего использования;
● в тонком клиенте и веб-клиенте с низкой скоростью соединения – через 20 минут после вычисления сохраняемого значения;
● при нехватке оперативной памяти в рабочем процессе сервера;
● при перезапуске рабочего процесса;
● при переключении клиента на другой рабочий процесс.
После удаления значений вызов экспортируемой функции выполняется как при первом вызове.
А нельзя ли ТАК правильно написать программный код, где «КЕШируемый» вызов будет получать данные только один раз( а не крутить вызовы в теле модуля)? И управление КЕШом всё-таки связать с видимостью ПЕРЕМЕННЫХ? Если пользователь «ушёл с модуля» — почистился КЕШ переменных значений модуля.
Вообще, как бы желательно, САМОМУ (программно) чистить КЕШ НЕ НУЖНЫХ значений(по типу деструктора).
И ещё. Если в общем модуле с повторным использованием выбран «на время сеанса», то чем ЭТО в принципе отличается от использовании параметров сеанса? Это я про «мусор» как в конфигурации, так и в головах
Для решения каких-то задач этот механизм наверняка нужен, удобен и хорош, но никакого отношения к «глобальным переменным на сервере» он не имеет, зачем писать такие вводящие в заблуждения названия статьям? Это «сохранение значения на сервере на время сеанса», а не глобальная переменная.
Переменная — это то, что можно изменить. Собственно, огромный кусок потребностей в глобальных переменных — это чтение-изменение её в разных местах. Есть у меня, например, глобальный счётчик, есть в разных местах процедуры, которые этот счётчик читают, а потом накручивают. Как это можно реализовать в данном механизме? Подозреваю, что как-то можно нахимичить с ОбновитьПовторноИспользуемыеЗначения(), но эти значения, собсна, для того и кэшировались, чтобы их как можно меньше дёргать, а так, получается, для каждого изменения нужно весь кэш сбрасывать (а его может быть очень много) для одной переменной.