Ты крутой дизайнер,
программист или просто
мастер своего дела?
Любишь технологии или татуировки и хотел бы
принять участие в разработке крупного
индустриального проекта?
О нас

Мы работаем над тату-проектом призванном объединить в себе людей, бизнес и технологии воедино. Наши главные задачи и миссия - собрать всех воедино, и предоставить равные условия и новые возможности, актуальные для каждого индивидуально.

Видео о нас
О нас

Мы работаем над тату-проектом призванном объединить в себе людей, бизнес и технологии воедино. Наши главные задачи и миссия - собрать всех воедино, и предоставить равные условия и новые возможности, актуальные для каждого индивидуально.

Видео о нас
Что такое ВТАТУ?
Это сервисы и технологии
Комплексные инфраструктурные решения
Медийная площадка
Crowd-based медиа
Рекомендательный сервис
Marketplace товаров и услуг
Blockchain платформа
Профессиональное сообщество
CRM для студий, салонов и мастеров
Сертификация тату-салонов и мастеров
Верифицированное портфолио мастеров
Что такое ВТАТУ?
Это люди
Неравнодушные к татуировкам и индустрии в целом
Художники по гриму и визажисты
Профессиональные фотографы
Любители и фанаты татуировок
Художники по волосам и стилисты
Мастера по перманентному макияжу
Мастера по пирсингу
Художники по эскизам
Тату-мастера
Тату фотомодели
Что такое ВТАТУ?
Это бизнес
Вовлеченный в индустрию татуировок и боди модификаций
Фотостудии
Салоны красоты и перманентного макияжа
Организаторы тату конвенций и мероприятий
Тату-студии и салоны
Школы татуировки
Медицинские центры
Тату воркспейсы
Бренды и производители медикаментов для ухода за татуировками
Что такое ВТАТУ?
Это возможности
Безопасно воспользоваться тату-услугами и найти нужных мастеров
Для организаторов тату конвенций и мероприятий
Для салонов красоты и перманентного макияжа
Для тату мастеров
Для фотографов, моделей, стилистов и визажистов
Для художников по эскизам
Для тату студий и салонов
Для тату мастеров
Для любителей и фанатов татуировок
Сделать татуировку с гарантией
Сделать татуировку с гарантией
Наша цель — покорить мир
  • 01

    Стать крупнейшим медиа комьюнити проектом индустрии

  • 02

    Задать новый стандарт взаимодействия между потребителями, бизнесом и частными мастерами тату

  • 03

    К 2024 году охватить 20% мирового рынка индустрии

Кто нам нужен?

Увлечённые люди, неравнодушные к тату, профессионалы своего дела и страстно желающие изменить мир.

Разработчики, дизайнеры и IT-специалисты для реализации и развития технологической составляющей.

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

И, просто фанаты тату для участия в жизни коммюнити и выполнения публичных bounty-задач.

Кто нам нужен?

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

Кого ищем?
  • PHP разработчик
    ас своего дела
  • UI дизайнер
    фанатичный педант
  • JavaScript-разработчик
    Мастер фронтенда
  • UI/UX проектировщик
    гуру прототипирования
  • Региональный репортёр
    в курсе всего происходящего
  • Social media manager
    сразу везде
  • Редактор
    зачитаешься!
  • Член сообщества
    это всё для меня!
  • DBA
    database overlord
  • QA тестировщик
    Шерлок Холмс в мире багов
  • Член команды поддержки
    любящий помогать другим
  • Android разработчик
    единомышленник Энди
  • iOS разработчик
    верный фанат творений Стива
PHP разработчик
ас своего дела

Задачи

  • Разработка программной платформы проекта (ядро);
  • Реализация и расширение бизнес-логики приложения (публичной, кабинета, CRM);
  • Разработка как внешнего API для сторонних разработчиков, так и внутренних нужд;
  • Интеграция со стороними сервисами и соцальными сетями;
  • Сode review членов команды.

Требования

  • огромное желание делать крутые продукты и развиваться;
  • хорошее знание PHP 5.6+ и 7.0+;
  • умение писать чёткий, структурированный и документированный код;
  • опыт работы с какими-либо PHP фреймворками;
  • знание ООП, MVС и умение применять основные паттерны проектирования кода;
  • базовые знания HTML, CSS, JS;
  • знание SQL баз данных, принципа их работы и оптимизации запросов;
  • опыт работы с Git;
  • умение работать и вести разработку в Linux;
  • знание основ информационной безопасности web-приложений, уметь выявлять и устранять их риски;
  • умение работать в команде и фанатеть о того, что ты делаешь.

Приветствуется

  • инициативность;
  • стремление к самообучению, изучению технологий и аппробации их на практике;
  • опыт Frontend разработки, знание нюансов, принципов построения и фреймворков;
  • Datomic, Neo4j, Cypher, графовые база данных;
  • MongoDB;
  • опыт интеграции с blockchain-решениями.
  • опыт разработки высоконагруженных проектов.

Конкретная сфера, узел и спектр задач определяется на этапе собеседования и исходя из ваших желаний: простор для творчества и профессиональной самореализации – это основа нашего проекта, и не только для тату-мастеров.

от 2'000 в месяц
или от 4'000 баунти
PHP разработчик
ас своего дела
UI дизайнер
фанатичный педант
Описание вакансии пока отсутствует
UI дизайнер
фанатичный педант
JavaScript-разработчик
Мастер фронтенда
Описание вакансии пока отсутствует
JavaScript-разработчик
Мастер фронтенда
UI/UX проектировщик
гуру прототипирования
Описание вакансии пока отсутствует
UI/UX проектировщик
гуру прототипирования
Региональный репортёр
в курсе всего происходящего
Описание вакансии пока отсутствует
Региональный репортёр
в курсе всего происходящего
Social media manager
сразу везде
Описание вакансии пока отсутствует
Social media manager
сразу везде
Редактор
зачитаешься!
Описание вакансии пока отсутствует
Редактор
зачитаешься!
Член сообщества
это всё для меня!
Описание вакансии пока отсутствует
Член сообщества
это всё для меня!
DBA
database overlord
Описание вакансии пока отсутствует
DBA
database overlord
QA тестировщик
Шерлок Холмс в мире багов
Описание вакансии пока отсутствует
QA тестировщик
Шерлок Холмс в мире багов
Член команды поддержки
любящий помогать другим
Описание вакансии пока отсутствует
Член команды поддержки
любящий помогать другим
Android разработчик
единомышленник Энди
Описание вакансии пока отсутствует
Android разработчик
единомышленник Энди
iOS разработчик
верный фанат творений Стива
Описание вакансии пока отсутствует
iOS разработчик
верный фанат творений Стива
Какие задачи предстоит решать
  • Группа разработки
  • Редакция
  • Продвижение и реклама
  • Группа поддержки пользователей
  • 01

    Расширение текущего и реализация нового функционала платформы, гео-масштабирование проекта.

  • 02

    Разработка публичных blockchain- и смарт-контракт решений для технологической инфраструктуры проекта.

  • 03

    Разработка интеграционных решений для бизнеса, мастеров и сторонних разработчиков.

  • 01

    Готовить интересные публикации, помогать остальным пользователям в их творчестве, и отбирать из всего этого лучшее.

  • 02

    Освещать все запланированные и проходящие поблизости, стране и мире тату-мероприятия и события.

  • 03

    Своим пером и на своём примере доносить до людей как саму философию проекта, так и любовь к тату как искусству.

  • 01

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

  • 02

    Помогать бизнесу и мастерам в продвижении их собственных услуги и привлечении клиентов.

  • 03

    Продвигать тату-культуру и философию проекта.

  • 01

    Активно помогать новым участникам осваиваться: добавлять свои тату, искать мастеров, и работать с клиентами.

  • 02

    Помогать пользователям в случае возникновения у них каких-либо затруднений и учавствовать в их решении.

  • 03

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

Какие задачи предстоит решать
Группа разработки
  • 01

    Расширение текущего и реализация нового функционала платформы, гео-масштабирование проекта.

  • 02

    Разработка публичных blockchain- и смарт-контракт решений для технологической инфраструктуры проекта.

  • 03

    Разработка интеграционных решений для бизнеса, мастеров и сторонних разработчиков.

Редакция
  • 01

    Готовить интересные публикации, помогать остальным пользователям в их творчестве, и отбирать из всего этого лучшее.

  • 02

    Освещать все запланированные и проходящие поблизости, стране и мире тату-мероприятия и события.

  • 03

    Своим пером и на своём примере доносить до людей как саму философию проекта, так и любовь к тату как искусству.

Продвижение и реклама
  • 01

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

  • 02

    Помогать бизнесу и мастерам в продвижении их собственных услуги и привлечении клиентов.

  • 03

    Продвигать тату-культуру и философию проекта.

Группа поддержки пользователей
  • 01

    Активно помогать новым участникам осваиваться: добавлять свои тату, искать мастеров, и работать с клиентами.

  • 02

    Помогать пользователям в случае возникновения у них каких-либо затруднений и учавствовать в их решении.

  • 03

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

ICO, баунти, блокчейн, токены
  • Номинальная стоимость 1 токена
    1.00 USD (~0.004 ETH)
  • Базовый объём эмиссии
    35 000 000 токенов (~35 000 000 USD)
  • Pre-ICO
    2 275 000 токенов (~2 275 000 USD)
  • ICO
    23 625 000 токенов (~23 625 000 USD)
  • Стоимость токена на Pre-ICO
    от 0.002 ETH (~0.50 USD)
  • Bounty кампания:
    4 200 000 токенов (~4 200 000 USD)
67.5%
ico
12%
bounty
1%
Советники
7%
Инвесторы
6%
Команда
6.5%
PRE-ICO
Форматы вознаграждения
  • Наличными

    Только наличными в фиате (доллары, рубли, евро) по среднерыночной цене или ставке.
    100 долл. - есть 100 долл.

  • 50/50

    50% – по рыночной цене в фиате, и 50% в токенах проекта.
    100 долл. = 50 долл. (кеш) + 50*2 (токены).

  • Bounty

    Полностью в токенах проекта в удвоенном объёме.
    100 долл. = 200 долл. (токены).

Bounty кампания
  • Публичная

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

  • Сообщество

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

  • Команда

    Только для членов команды, вносящих наибольший личный вклад в развитие сообщества. Часть заданий может быть видна только для участников и аудиторов.

Кто нам нужен для Bounty

Bounty-хантеры желающие просто заработать, или мастера, любители и фанаты татуировки не равнодушные к проетку, его идеалам и миссии желающие внести свою посильную лепту в его в развитие.

Кто нам нужен?

Bounty-хантеры желающие просто заработать, или мастера, любители и фанаты татуировки не равнодушные к проетку, его идеалам и миссии желающие внести свою посильную лепту в его в развитие.

  • Дизайн-макет посадочной страницы "У тебя клёвое тату"
    1'000.00
    до 3'000.00
  • Визитка-пригласительный "У тебя клёвое тату!"
    200.00
  • Аватарки для официальных сообществ проекта
    100.00
  • Аватарки для неавторизованных пользователей
    100.00
  • Invite your friends
    5.00
  • Sign up as user
    10.00
  • Поделиться нашими постами в Twitter
    0.20
  • Поделиться нашими постами в ВКонтакте
    0.20
  • Поделиться нашими постами в Facebook
    0.20
  • Подписаться на наш Telegram канал
    1.00
  • Подписаться на наш Instagram канал
    1.00
  • Подписаться на наш Twitter канал
    1.00
  • Присоединиться к странице сообщества в ВКонтакте
    1.00
  • Присоединиться к странице сообщества в Facebook
    1.00
  • Website and application translations
    20.00
    до 3'000.00
  • New promo video for ICO campaign
    100.00
    до 10'000.00
  • New promo video
    100.00
    до 10'000.00
  • New banners for ICO campaign
    5.00
    до 100.00
  • New banners for our project
    5.00
    до 100.00
  • Send bug reports
    1.00
    до 100'000.00
Дизайн-макет посадочной страницы "У тебя клёвое тату"
Описание задачи
Роль и назначение - приветственная (первая с которой встречается пользователь) страница проекта, на которую посетитель попадает по пригласительному мастера, через соц. сети, скан QR-кода раздаточной листовки-визитки. (так же, может быть переход по рекламной кампании).
На первом слайде фигурирует "У тебя клёвое тату!" Присоединяйся! "(будь ВТАТУ, опционально). Далее, если приглашение было от конкретного лица, отображается кто пригласил, как сейчас только лучше. Если пригласительный персональный - т.е. для индивидуально для этого посетителя - можно отобразить его имя и сообщение от пригласившего. (на текущей странице отображается по клику на портрет пригласившего см. пример)
На следующем слайде - регистрация (соц. сети или логин/пароль + ввод имени и пола). Сама регистрация проходит без перезагрузки страницы. После регистрации на этом слайде отображается сообщение - "Вы успешно зарегистрированы! Идёт дальше". Текст можно менять для лучшего соответствия.
Следующий слайд - добавление тату в упрощённой форме - только фотография, название и описание (не обязательное) и отметка что можно будет потом описать более детально. Либо, переключение простое добавление или подробное (с вводом/выбором мастера, стори, места  и т.д.).
Следующий финальный слайд - приветственное поздравительное сообщение. В духе теперь "ты тоже ВТАТУ!". после верификации ты получишь / на твой счёт будет зачислено 10 токенов/(экв. 10 долл). О токенах можно упомянуть и на  первом слайде, по-желанию.
След (служебный слайд) - произвольная информация (ссылки проекта), например, переход к пригласившему и добавление его в друзья, просмотр мастеров, студий. и т.д. Можно указать линк/ блок страницы team.vtatu.com. Но, без сильной перегрузки.
Всего можно будет принято три варианта (желательно от разных лиц), которые будут в равной степени интегрированы и показаны в случайном порядке (A/B-тестирование на предмет выявления лучшего). Указанное вознаграждение получит каждый. Лучший вариант / страница будут так же награждены удвоенным бонусом (2000 VTTI), таким образом суммарно лучший получит эквивалент в 3000 долл, 2 других участника по 1000. И, все три одинаково на равных будут отмечены контрибьюторах и участниках команды, если таковыми ещё не являются)
1'000.00
от 1'000.00 до 3'000.00
Дизайн-макет посадочной страницы "У тебя клёвое тату"
от 1'000.00 до 3'000.00
Визитка-пригласительный "У тебя клёвое тату!"
Описание задачи
Идёшь ты по улице и  видишь у человека тату и просто, возможно даже без слов, или кратко , произнеся только  "У тебя клёвое тату! Присоединяйся!" вручаешь ему "визитку". На которой крупными буквами сразу же видна эта фраза.
На  оборотной  можно разместить например, "Будь ВТАТУ!", но это под вопросом - и лишь как вариант.
На оборотной стороне можно разместить пару слов о проекте, если они впишутся и не перегрузят. И, либо QR-код с пригласительным, как сейчас на визитке (см. фото), и/или ссылка (адрес сайта) текстом и код самого пригласительного буквами.
Тут  есть два варианта, для части людей мастеров,  абмассадоров,  и др, например, их можно персонализированно в типографии. Но, нужно быть готовым что это не удастся сделать для всех. Поэтому, возможно, стоит рассмотреть вариант с полем на написания кода от руки. (если конечно  смотреться это будет не совсем дешмански...)
Так же можно будет указать информацию о том, что добавь свои тату  и получи бонус (баунти) от проекта. Главное что бы не выглядело слишком рекламно. Мы не впариваем туфту - мы вовлекаем людей в проект/сообщество.
Для мастеров и амбассадоров будут отдельные визитки указанием их контактов, кто он и кем является. На это будет отдельное задание, но в идеале  что бы их вид был согласован с этими. Но, не обязательно. Полная свобода экспериментов  - наш второй лозунг, как ни как)))
 
P.S.
И, да, почему "визитка"? Ведь там нет никаких контактных личных данных (вернее они не обязательны).
Потому, что размером с визитку. И, роль такая же, только не для персоны или компании, а для сообщества.
200.00
200.00
Визитка-пригласительный "У тебя клёвое тату!"
200.00
Аватарки для официальных сообществ проекта
Описание задачи
Сейчас используются эти простые вариации "на коленке" на тему основного логотипа см. вложенные изображения.
Необходимо составить концепцию единого общего вида аватарок для текущих и будущих оффициальных сообществ проекта.
Текущие это:
Далее, крайне было бы полезным использовать единый концепт для региональных сообществ. 
Например, ВТАТУ Россия  (Россия ВТАТУ))), ВТАТУ Украина, ВТАТУ Китай, а так же ВТАТУ Москва, ВТАТУ Белгород, ВТАТУ Краснодарский край / Сочи. 
Для данных, например, можно использовать вариацию / игру с флагом/гербом внизу справа, или через угол. Хотя и необязательно - главное сделать красиво. Учесть что они так же могут и будут использованы для представительств   в Facebook, ВК, Instagram, Twitter.
Для этих соц. сетей подготовить соответсвующие форм факторы изображений.
100.00
100.00
Аватарки для официальных сообществ проекта
100.00
Аватарки для неавторизованных пользователей
Описание задачи
Набор аватарок для неаутентифицированных (неавторизованных) пользователей.
Сейчас для неавторизованных пользователей и тех кто ещё не установил свой аватар по-умолчанию показываются случайные изображения ("коты"). Это не всегда хорошо. Подобная ми-ми-мишая няшность-милашность резко контрастирует с тематикой и темой (оформлением сайта), не говоря уже о том, что кто-то может больше любить собак))).
Необходим набор изображений (аватарок) на замену по крайней мере по 5* для каждого пола. Использовать  фотографии и изображения с конкретными ныне живущими людьми, не желательно в  силу объективных причин))) Аналогично, само собой касается изображений из фото стоков.
Хотя, например, в качестве идеи - можно задействовать известных исторических лиц в татухах, конечно предварительно стилизовав.
В идеале, это специально сделанные (нарисованные) картинки  сделанные специально для ВТАТУ. При этом было бы вообще шикарно учесть гармонию как с текущим дизайном, так и новым, который уже готовим к выпуску (скрины будут приложены к заданию, и/или при желании, после переписки в телеграме, можем прислать и макет в Sketch-е).
* - можно и больше. Всё учтётся ;)
100.00
100.00
Аватарки для неавторизованных пользователей
100.00
Invite your friends
Описание задачи
Tell your friends about us and invite 'em
5.00
5.00
Invite your friends
5.00
Sign up as user
Описание задачи
Sign up as user on our website
10.00
10.00
Sign up as user
10.00
Поделиться нашими постами в Twitter
Описание задачи
Поделиться нашими постами в Twitter
0.20
0.20
Поделиться нашими постами в Twitter
0.20
Поделиться нашими постами в ВКонтакте
Описание задачи
Поделиться нашими постами в ВКонтакте
0.20
0.20
Поделиться нашими постами в ВКонтакте
0.20
Поделиться нашими постами в Facebook
Описание задачи
Поделиться нашими постами в Facebook
0.20
0.20
Поделиться нашими постами в Facebook
0.20
Подписаться на наш Telegram канал
Описание задачи
Подписаться на наш Telegram канал
1.00
1.00
Подписаться на наш Telegram канал
1.00
Подписаться на наш Instagram канал
Описание задачи
Подписаться на наш Instagram канал
1.00
1.00
Подписаться на наш Instagram канал
1.00
Подписаться на наш Twitter канал
Описание задачи
Подписаться на наш Twitter канал
1.00
1.00
Подписаться на наш Twitter канал
1.00
Присоединиться к странице сообщества в ВКонтакте
Описание задачи
Присоединиться к странице сообщества в ВКонтакте
1.00
1.00
Присоединиться к странице сообщества в ВКонтакте
1.00
Присоединиться к странице сообщества в Facebook
Описание задачи
Присоединиться к странице сообщества в Facebook
1.00
1.00
Присоединиться к странице сообщества в Facebook
1.00
Website and application translations
Описание задачи
Help us translate our website and application in more languages
20.00
от 20.00 до 3'000.00
Website and application translations
от 20.00 до 3'000.00
New promo video for ICO campaign
Описание задачи
New promo video for ICO campaign of our project
100.00
от 100.00 до 10'000.00
New promo video for ICO campaign
от 100.00 до 10'000.00
New promo video
Описание задачи
New promo video for our project
100.00
от 100.00 до 10'000.00
New promo video
от 100.00 до 10'000.00
New banners for ICO campaign
Описание задачи
New banners for ICO campaign of our project
5.00
от 5.00 до 100.00
New banners for ICO campaign
от 5.00 до 100.00
New banners for our project
Описание задачи
New banners for our project
5.00
от 5.00 до 100.00
New banners for our project
от 5.00 до 100.00
Send bug reports
Описание задачи
Send bug reports
1.00
от 1.00 до 100'000.00
Send bug reports
от 1.00 до 100'000.00
Кто уже с нами в формате Bounty?
Константин
Frontend разработчик
Михаил Дергачев
Frontend разработчик
Никита Шубин
Product Designer
Александр Черных
Software Architect, founder
Кто уже с нами в формате Bounty?
Robby
Тату мастер
Игорь Пуржинский
Основатель
Ева
Тестировщик
Что у нас есть сейчас
На данный момент мы перерабатываем графическое представление дорожной карты проекта.
Контакты
Мы на карте
Москва, Краснохолмская набережная, 34, стр. 3,оф. 560
Присоединиться к команде
кто мы
0
Произошла ошибка! @team.vtatu.com __Shutdown_Decorator::renderErrorReport
Ошибка типа [1]: [
Uncaught *{DB\Exception}:
[1114][The table 'Statistics_RequestJournal_Records' is full]

BD={MySQL}
SQL=[INSERT INTO 
		`Statistics_RequestJournal_Records` 
 (
		`ID`, 
		`GUID`, 
		`POUUID`, 
		`ClassName`, 
		`ParentGUID`, 
		`OwnerGUID`, 
		`timeCreated`, 
		`timeModified`, 
		`timeAccessed`, 
		`Description`, 
		`Comments`, 
		`CodeID`, 
		`VersionString`, 
		`Name`, 
		`Hash`, 
		`Order`, 
		`Active`, 
		`timeSynchronized`, 
		`Owner_GUID`, 
		`Owner_POUUID`, 
		`Owner_ClassName`, 
		`Owner_Active`, 
		`ParentObject_GUID`, 
		`ParentObject_POUUID`, 
		`ParentObject_ClassName`, 
		`ParentObject_VersionString`, 
		`Tags`, 
		`REQUEST_METHOD`, 
		`UNIQUE_ID`, 
		`RequestTime_Start`, 
		`HTTP_SCHEME`, 
		`HTTP_HOST`, 
		`HTTP_URL`, 
		`QUERY_STRING`, 
		`HTTP_REFERER`, 
		`HTTP_REFERER_HOST`, 
		`Request_Headers_JSON`, 
		`SessionID`, 
		`Client_IP`, 
		`Client_UserAgent`, 
		`Client_IsRobot`, 
		`Client_IsSearchEngineCrawler`, 
		`Client_IsVulnerabilityScanner`, 
		`Client_Robot_Type`, 
		`Client_Robot_Fami
] в файле [/home/www-master/www/apps/HostSystem/SharedApps/moonlite13.cmf/core.moonlite13.ru/Modules/DBManagement/classes/class.DB_SQL.php] в строке [654]

Текущее(реальное) использование памяти [25'105'432] (25'952'256) из [512M] разрешённых
Участок с ошибкой:
00650:
        }
00651:
        //\System::LoadObjectsList($class_name, $Groups);
00652:
        //var_dump($query);
00653:
        
00654:        throw new \DB\Exception (
00655:
             sprintf(
00656:
                "*Ошибка при исполнении SQL запроса! <br /> MySQL error:[<b>%s</b>]\n While [<b>%s</b>] \n callstack:\n <pre>%s</pre>"
00657:
                ,$message
00658:
                ,$query
00659:
                ,$_tmp_debug_print_backtrace
00660:
            )


Файл целиком:
<?php
/**
 * Класс DB, обеспечивающий работу с SQL базами данных
 * 
 * 
 * @package     DBManagement
 * @author      Premier13 (Черных Александр) <alex@sensei.su>
 * @copyright   Sensei Media Concept(C) 2006
 *
 */
class DB_SQL
    
implements \JsonSerializable
{
    const 
DB_CATEGORY_SQL       "SQL";
    const 
DB_CATEGORY_NOSQL     "NoSQL";
    
    const 
DB_TYPE_MYSQL         "MySQL";
    const 
DB_TYPE_MSSQL         "MSSQL";
    const 
DB_TYPE_ORACLE        "Oracle";
    const 
DB_TYPE_POSTGRESQL    "PostgreSQL";
    
    
    const 
DB_ROLE_PERSISTENT    "Persistent Storage";
    const 
DB_ROLE_TEMPORARY     "Temporary Storage";
    
    
    
    
    const 
INDEX_TYPE_BTREE      "BTREE";
    const 
INDEX_TYPE_FULLTEXT   "FULLTEXT";
    const 
INDEX_TYPE_HASH       "HASH";
    const 
INDEX_TYPE_RTREE      "RTREE";
    
    
    
    
    protected 
$DB_CATEGORY  self::DB_CATEGORY_SQL;
    protected 
$DB_TYPE      self::DB_TYPE_MYSQL;
    protected 
$DB_ROLE      self::DB_ROLE_PERSISTENT;
    
    const 
PROVIDER_ID       NULL;
    
    
    
/**
     * Имя сервера
     *
     * @var string
     */
    
public $dbServer;
    
/**
     * Имя базы активной данных
     *
     * @var string
     */
    
public $dbName;
    
/**
     * Имя пользователя БД
     *
     * @var string
     */
    
public $dbUser;
    
/**
     * Пароль пользователя БД
     *
     * @var string
     */
    
public $dbPass;
    
    
    
    
/**
     * Ссылка на подключение к базе данных
     *
     * @var mixed
     */
    
var $dbConnection;
    
    
    
    
    
    
    
/**
     * Счётчик выполненных запросов к базе данных
     *
     * @var integer
     */
    
var $dbqQueryCounter;
    
/**
     * Лог запросов (текстовый)
     *
     * @var string
     */
    
var $QueryLog;
    
    
    
    var 
$QueryLog_microtime_b;
    var 
$QueryLog_microtime_e;
    var 
$QueryLog_delta;
    var 
$QueryLog_query;
    
    
    
/**
     * Суммарное время выполнения запросов
     *
     * @var float
     */
    
var $sum_delta;                 #time
    
    
    
    
    
    /**
     * Флаг разрешаюшие логирование запросов
     *
     * @var boolean
     */
    
var $enableLogging;
    
/**
     * Структура логов запросов (Порядковый номер, время, время исполнения, запрос)
     *
     * @var MemoryLog
     */
    
protected $_log;
    
    protected 
$_is_persistent_connection    =   false;
    
    protected 
$_is_persistent_connection_enabled    =   true;
    
    protected 
$_is_db_selected false;
    
    
    
//TODO: Реализовать!
    
var $_access_level;
    var 
$_access_rights;
    var 
$_alowed_operators;
    var 
$_alowed_queries;
    
    
    
    
    
    
    
/**
     * Конструктор
     *
     * @param string $server
     * @param string $name
     * @param string $user
     * @param string $pass
     */
    
public function __construct($server="localhost",$name="database",$user="root",$pass="rootpass")
    {
        
$this->dbServer         =   $server;
        
$this->dbName           =   $name;
        
$this->dbUser           =   $user;
        
$this->dbPass           =   $pass;
        
//
        
$this->sum_delta        =   0;
        
//
        
$this->enableLogging    =   true;
        
//
        
$this->_log             =   new MemoryLog();
    }
    
/**
     * Деструктор
     *
     */
    
public function __destruct()
    {
        if(!
$this->isConnectionPersistent())
        {
            if(
$this->isConnected())
            {
                
$this->disconnect();
            }
        }
    }
     
/**
     * Отключение возможности клонирования объекта.
     * Реализация шаблона Singleton
     *
     * @ignore
     */
    
private function __clone() {}
    
    
/**
     *
     * @return string
     */
    
function getProviderType()
    {
        return 
"MySQL";
    }
    
    
/**
     *
     * @return string
     */
    
function getLastErrorNo()
    {
        return 
mysql_errno($this->getDBConnection());
    }
    
/**
     *
     * @return string
     */
    
function getLastErrorMessage()
    {
        return 
mysql_error($this->getDBConnection());
    }
    
    
    
    
/**
     * Получить категорию БД
     *
     * @return string
     */
    
function getCategory()
    {
        return 
$this->DB_CATEGORY;
    }
    
    
/**
     * Получить тип базы данных
     * 
     * @return string
     */
    
function getType()
    {
        return 
$this->DB_TYPE;
    }
    
    
    function 
getRole()
    {
        return 
$this->DB_ROLE;
    }
    
    
/**
     * Получить имя сервера
     *
     * @return string
     */
    
public function getServerName ()
    {
        
$result =   $this->dbServer;
        return 
$result;
    }
    
    
/**
     * Получить имя активной базы данных в подключении
     *
     * @return string
     */
    
public function getDBName ()
    {
        
$result =   $this->dbName;
        return 
$result;
    }
    
/**
     * 
     * @param string $value
     * @return DB_SQL
     */
    
function &setDBName($value)
    {
        
$this->dbName $value;
        return 
$this;
    }
    
    
    
/**
     * 
     * @return string
     */
    
public function getUserName()
    {
        return 
$this->dbUser;
    }
    
/**
     * 
     * @return string
     */
    
public function getUserPassword()
    {
        return 
$this->dbPass;
    }
    
    
    
    
/**
     * Реализация метода интерфейса JsonSerializable (PHP 5 >= 5.4.0, PHP 7)
     *
     * Цель метода - исключение проблем с сериализацией объектов
     *  и в частности наличием в них переменных типа resource.
     *  
     * @see http://php.net/manual/ru/jsonserializable.jsonserialize.php
     *
     *
     *
     *
     * @return string
     */
    
function jsonSerialize()
    {
        
$result = array();
        
//
        
$result["Server"]   = $this->dbServer;
        
$result["Databale"] = $this->dbName;
        
$result["User"]     = $this->dbUser;
        
$result["Passowrd"] = $this->dbPass;
        
//
        
$result["IsPersistentConnection"]        = $this->_is_persistent_connection;
        
$result["IsPersistentConnectionEnabled"] = $this->_is_persistent_connection_enabled;
        
$result["IsDbSelected"]                  = $this->_is_db_selected;
        
//
        
$result["Connection"] = $this->dbConnection true false;
        
//
        
        
        
        
        
$result["enableLogging"] = $this->enableLogging;
        
//
        
$result["QueryLog"]        = $this->QueryLog;
        
        
        
$result["QueryLog_microtime_b"] = $this->QueryLog_microtime_b;
        
$result["QueryLog_microtime_e"] = $this->QueryLog_microtime_e;
        
$result["QueryLog_delta"]       = $this->QueryLog_delta;
        
$result["QueryLog_query"]       = $this->QueryLog_query;
        
        
// Суммарное время выполнения запросов
        
        
$result["TotalDBTimeUsed"]      = $this->sum_delta;
        
$result["TotalQueriesCount"]    = $this->dbqQueryCounter;
        
        
//
        
$result["sum_delta"]       = $this->sum_delta;
        
$result["dbqQueryCounter"] = $this->dbqQueryCounter;
        
        
//
        
        
        
        //
        //$this->_log             =   new MemoryLog();
        
        
        
        
        
        //return $this->toSimpleArray();
        //
        
return $result;
    }
    
    
    
/**
     * 
     * @return number
     */
    
function getTotalQueriesCount()
    {
        return 
$this->dbqQueryCounter;;
    }
    
/**
     *
     * @return number
     */
    
function getTotalDBTimeUsed()
    {
        return 
$this->sum_delta;;
    }
    
    
    function &
connect()
    {
        
//
        
$this->dbConnection     =   mysql_pconnect($this->dbServer$this->dbUser$this->dbPass);
        if(!
$this->dbConnection)
        {
            
// TODO: пересмотреть!
            
$_tmp_debug_print_backtrace =   "";
                
ob_start();
                    
debug_print_backtrace();
                    
$_tmp_debug_print_backtrace =   ob_get_contents();
                
ob_end_clean();
                
//
            
throw new DBException (
                 
sprintf(
                    
"Ошибка при подключении к серверу БД! <br /> MySQL error:[<b>%s</b>]\n While [<b>CONNECT TO BD Server</b>] \n callstack:\n <pre>%s</pre>"
                    
,mysql_error()
                    
//,$query
                    
,$_tmp_debug_print_backtrace
                 
)
                ,
503
              
);
            
//$result = false;
            
die("503");
            
//
        
}
        
$this->_is_persistent_connection    =   true;
        
//
        
        
if($this->isConnected())
        {
            
$this->onConnect();
        }
        
        return 
$this;
    }
    
    function &
disconnect()
    {
        if(
$this->isConnected())
        {
            
        }
        
        return 
$this;
    }
    
    
/**
     * Подключена ли БД
     *
     * @return boolean
     */
    
function isConnected()
    {
        return 
$this->dbConnection true false;
    }
    
    function 
isConnectionPersistent()
    {
        return  
$this->_is_persistent_connection;
    }
    
    function &
onConnect()
    {
        
$this->resetCounters();
        
//
        
$queries   = array();
        
$queries[] = "SET NAMES UTF8;";
        
$queries[] = "SET COLLATION_CONNECTION=UTF8_GENERAL_CI;";
        
        
        
// @todo только на текстовых полях и полях ввода пользователями (соц.сети)
        // Storage for variable-length columns includes length bytes, 
        // which are counted toward the row size. 
        // For example, a VARCHAR(255) CHARACTER SET utf8mb3 column 
        // takes two bytes to store the length of the value, so each value can take up to 767 bytes.
        //$queries[] = "SET COLLATION_CONNECTION=utf8mb4_unicode_ci;";
        
        // https://mathiasbynens.be/notes/mysql-utf8mb4
        //$queries[] = "SET COLLATION_CONNECTION=utf8mb4_unicode_ci;";
        
        //
        // The default SQL mode in MySQL 5.7 includes these modes: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, and NO_ENGINE_SUBSTITUTION.
        // SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '0000-00-00 00:00:00' for column
        
$queries[] = "SET SQL_MODE='ALLOW_INVALID_DATES';";
        
//
        
foreach($queries as $query)
        {
            
//$Result1    =   $this->ExecQuery($query,false);
            
            
if(!$this->execQuery($query,false))
            {
                
//
            
}
        }
        
//
        
return $this;
    }
    
    function 
selectDB($dbname)
    {
        return 
false;
    }
    
    
    
    function 
onConnectionError($errorno,$message)
    {
        
//
        
$_tmp_debug_print_backtrace =   "";
        
//
        
ob_start();
        
debug_print_backtrace();
        
$_tmp_debug_print_backtrace =   ob_get_contents();
        
ob_end_clean();
        
//
        
throw new \DB\Exception (
            
sprintf(
                
"Ошибка при подключении к серверу БД!"."<br />"
                
."Ошибка:[<b>%s</b>] (<b>%s</b>)"."<br />"
                
."Стэк вызова:"."<br />"
                
."<pre>%s</pre>"
                
,$message
                
,$errorno
                
//,$query
                
,$_tmp_debug_print_backtrace
            
)
            ,
503
            
,$this
        
);
        
$result false;
        
//
        
die("503");
        
//
        
return $result;
    }
    
    
    
    
    
    
    function 
onSwitchDbError($dbname,$errorno,$message)
    {
        
// Временное решение! TODO: довести до ума!
        
if(class_exists("__Shutdown_Processor"))
        {
            @
ini_set('display_errors'false);
        }
        
//
        //echo "<pre>";            debug_print_backtrace(); echo "</pre>";            die();
        //
        
$_tmp_debug_print_backtrace =   "";
        
ob_start();
        
debug_print_backtrace();
        
$_tmp_debug_print_backtrace =   ob_get_contents();
        
ob_end_clean();
        
//
        
throw new \DB\Exception (
            
sprintf(
                
"Ошибка при переключении на БД [<b>%s</b>]!"."\n<br />\n"
                
."Ошибка:[<b>%s</b>] (<b>%s</b>)"."<br />"
                
."\n<br />\n"
                
."\n<br />\n"
                
."Стэк вызова:"."<br />"
                
,$dbname
                
,$message
                
,$errorno
                
,$_tmp_debug_print_backtrace
            
)
            ,
503
            
,$this
            
,""
            
,debug_backtrace()
        );
        
//
        
$result false;
        die(
"503");
        
//
        
return $result;
    }
    
    
    
    
    
/**
     * 
     * @global Engine $engine
     * 
     * @param string $query
     * @param string $errorno
     * @param string $message
     * @throws DBException
     * @return boolean
     */
    
function onQueryError($query,$errorno,$message)
    {
        global 
$engine;
        
        
// Временное решение! TODO: довести до ума!
        
if(class_exists("__Shutdown_Processor"))
        {
            @
ini_set('display_errors'false);
        }
            
        if(
$engine->isDevServer())
        {
            echo 
sprintf(
                 
"[%s]< br />"
                
,$message
                
//,$query
            
);
        }
        
        
$_tmp_debug_print_backtrace =   "";
        
        
ob_start();
        
debug_print_backtrace();
        
$_tmp_debug_print_backtrace =   ob_get_contents();
        
//die($query);
        //
        
ob_end_clean();
        
//
        
        
        
if(1)
        {
            
error_log($query);
            
//error_log($_tmp_debug_print_backtrace);
            
            
$_trace_stack debug_backtrace();
            
array_shift($_trace_stack);
            
            
            
$___log "";
            
            foreach(
$_trace_stack as $key => $record)
            {
                
//
                // Борьба с наличием рекурсии
                //$backtrace = unserialize(    serialize(debug_backtrace()));
                //
                //$___args    =   NULL;
                //$___args    =   (isset($_trace_stack[$key]["args"])) ? unserialize(serialize($_trace_stack[$key]["args"])) : $___args;
                //
                
$___log .= sprintf(
                    
"#%s [%s] [%s][%s][%s] (%s); on [%s:%s] \n"
                    
,$key
                    
,(isset($record["object"])                                          ? get_class($record["object"])  : "")
                    ,(isset(
$record["class"]))                                          ? $record["class"]              : ""
                    
,(isset($record["type"]))                                           ? $record["type"]               : ""
                    
,(isset($record["function"]))                                       ? $record["function"]           : ""
                    
/*,(isset($_trace_stack[$key]["args"])
                    AND is_array($_trace_stack[$key]["args"]))
                    ?
                    //implode(",",$_trace_stack[$key]["args"])
                    //"I::".
                    \Debug::implode_func_arg($_trace_stack[$key]["args"])
                    //."<br />".print_r($_trace_stack[$key]["args"],true)
                      :
                     ((isset($_trace_stack[$key]["args"]))                                       ? \Debug::implode_func_arg($_trace_stack[$key]["args"])           : "")
                    */
                    
,"..."
                    
,(isset($record["file"]))                                       ? $record["file"]           : "?"
                    
,(isset($record["line"]))                                       ? $record["line"]           : "?"
                
);
            }
            
error_log($___log);
            
//error_log(Debug::Bugtrace("ext",true,false,$_trace));
        
}
        
//\System::LoadObjectsList($class_name, $Groups);
        //var_dump($query);
        
        
throw new \DB\Exception (
             
sprintf(
                
"*Ошибка при исполнении SQL запроса! <br /> MySQL error:[<b>%s</b>]\n While [<b>%s</b>] \n callstack:\n <pre>%s</pre>"
                
,$message
                
,$query
                
,$_tmp_debug_print_backtrace
            
)
            ,
503
            
,$this
            
,$query
            
,debug_backtrace()
        );
        
$result false;
        die(
"503");
        
        return 
$result;
    }
    
    
/**
     * 
     * @param mixed $handle
     * @return NULL
     */
    
function &instantiateQueryResult($handle=NULL)
    {
        
$result = new \DBQueryResult();
        
//
        
if($handle)
        {
            
$result->setHandle($handle);
        }
        
//
        
return $result;
    }
    
    
    
    
    
    
    
    
    function &
resetCounters()
    {
        
//
        
$this->dbqQueryCounter  =   0;
        
$this->sum_delta        =   0;
        
//
        
return $this;
    }
    
    
/**
     * 
     * @return self
     */
    
function &disableLogging()
    {
        
$this->enableLogging false;
        
//
        
return $this;
    }
    
/**
     * 
     * @return self
     */
    
function &enableLogging()
    {
        
$this->enableLogging true;
        
//
        
return $this;
    }
    
    
    
/**
     * Инициализация подключения к БД
     *
     */
    
public function dbInit()
    {
        
$this->connect();
    }
    
/**
     * Закрытие подключения к БД
     *
     * @return boolean
     */
    
public function dbClose()
    {
        
$this->disconnect();
    }
    
    
    
    
    
    
    
    
    
    
    
    
/**
     * Исполнение SQL запроса
     *
     * @global $engine
     * @param string $query SQL запрос
     * @param boolean $do_dbselect флаг разрешающий выбор SQL БД при исполнении запроса
     * @return resource результат выполения запроса (mysql_result)
     */
    
public function &ExecQuery($query,$do_dbselect=true)
    {
        
$result NULL;
        return 
$result;
    }
    
    
    
    
/**
     * Расширенная функция (метод) выполнения SQL-запроса
     *
     * @param SQLQuery $query
     * @param boolean $do_dbselect
     * @throws DBException
     * @return DBQueryResult
     */
    
public function &ExtendedExecQuery($query,$do_dbselect=true)
    {
        
$result NULL;
        return 
$result;
    }
    
/**
     * 
     * @param \SQLQuery $query
     * @param boolean $do_dbselect
     * @return \DBQueryResult
     */
    
public function &execQueryExtended($query,$do_dbselect=true)
    {
        if(
is_string($query))
        {
            return 
$this->instantiateQueryResult($this->ExecQuery($query));
        }
        
//
        
return $this->instantiateQueryResult($this->ExecQuery($query->toSQL()));
        
    }
    
    
    
        
    
    
    
    
/**
     * Получение числа записей получаемых при выполнении SQL запроса
     *
     * @param string $query SQL запрос
     * @param boolean $do_dbselect флаг разрешающий выбор SQL БД при исполнении запроса
     * @return integer $this->ExecQuery($query,$do_dbselect);
     */
    
public function getQueryRowsCount($query,$do_dbselect=false)
    {
        
$result NULL;
        
//
        
$query         =   str_replace(" * "," COUNT(*) as `num_count` ",$query);
        
//
        
$dbresult      =   $this->ExtendedExecQuery($query,$do_dbselect);
        
//
        
if($dbresult)
        {
            
$row_recordset =   $dbresult->getCurrentRowRecordset("assoc");
            
$result        =   $row_recordset['num_count'];
            
//
            
$dbresult->free();
        }
        
//
        
return $result;
    }
    
    
/**
     * 
     * 
     * @deprecated
     * 
     * @param string $query
     * @param boolean $do_dbselect
     * @return array
     */
    
function DBQueryResultAsArray($query,$do_dbselect=true)
    {
        
$result = array();
        
//
        
$dbresult      =   $this->ExtendedExecQuery($query,$do_dbselect);
        
//
        
if($dbresult)
        {
            
$result        =   $dbresult->asArray(true);
        }
        
//
        
return $result;
    }
    
    
    
    
    
    
/**
     * Получение списка имён баз данных на текущем сервере
     * (Замена mysql_list_dbs($this->dbConnection);)
     *
     * SHOW databases [ LIKE wild-card ]
     *
     * @return array
     */
    
public function getDBs ()
    {
        
$result =   array();
        
//
        
$query      =   'SHOW DATABASES';
        
$dbresult   =   $this->ExtendedExecQuery($query,false);
        
//
        
while ($rec_db  =   $dbresult->getCurrentRowRecordset(DBQueryResult::FETCH_MODE_INDEX))
        {
            
$result[]   =   $rec_db[0];
        }
        
//
        
$dbresult->free();
        
//
        
return $result;
    }
    
    
    
    
    
/**
     * Получение списка имён таблиц выбранной базы данных
     *
     * @param string $db_name имя базы данных
     * @return array
     */
    
public function getDBTables ($db_name=NULL)
    {
        
$result =   array();
        
//
        
if(!mb_strlen($db_name))
        {
            
$db_name      =   $this->getDBName();
        }
        
//
        //SHOW [FULL] TABLES [FROM db_name]  [LIKE 'pattern' | WHERE expr]
        //
        
$query      =   "SHOW TABLES FROM ".$this->quoteIdentifier($db_name).";";
        
//
        
$dbresult   =   $this->ExtendedExecQuery($query,false);
        
//
        
while ($row  =   $dbresult->getCurrentRowRecordset(DBQueryResult::FETCH_MODE_INDEX))
        {
            
$result[]   =   $row[0];
        }
        
//
        
$dbresult->free();
        return 
$result;
    }
    
    
/**
     * 
        Table
        Non_unique
        Key_name
        Seq_in_index
        Column_name
        Collation
        Cardinality
        Sub_part
        Packed
        Null
        Index_type
        Comment
        Index_comment

     * @param string $table_name
     * @param mixed $filter
     * @param array $options
     * @return mixed[]|NULL[]
     */
    
function getDBTableIndexes($table_name,$filter=NULL,$options=array())
    {
        
$result =   array();
        
//
        
        //
        /*
        $default_filter = array(
            "Index_type" => array(),
        );
        */
        //
        
$query      =   "SHOW INDEX FROM ".$this->quoteIdentifier($table_name).";";
        
//
        
if(count($filter))
        {
           if(isset(
$filter["Index_type"]) AND count($filter["Index_type"]))
           {
               
$condition = \DBPropertyCondition::instantiate("Index_type"                   ,$filter["Index_type"]    ,"IN");
               
               
               
//System::PrintArray($condition->toSQL());
               
               
               
$query      =   "SHOW INDEX \n FROM \n".$this->quoteIdentifier($table_name)."\n WHERE \n".$condition->toSQL().";";
               
           }
        }
        
//
        //System::PrintArray($query);
        //
        
$dbresult   =   $this->ExtendedExecQuery($query,false);
        
//
        
while ($row  =   $dbresult->getCurrentRowRecordset(DBQueryResult::FETCH_MODE_ASSOC))
        {
            
//$result[]   =   $row[0];
            
$result[]   =   $row;
        }
        
//
        
$dbresult->free();
        return 
$result;
    }
    
    
/**
     * 
     * @param string $table_name
     * @param string $fields
     * @param string $index_name
     * @param array $options
     * @return DBQueryResult
     */
    
function &addFullTextIndexTo($table_name,$fields,$index_name NULL,$options=array())
    {
        
//$fields_string = "";
        //
        
        //
        
$fields_quoted = array();
        
//
        
foreach ($fields as $key => $field_name)
        {
            if(
strlen($field_name))
            {
                
$fields_quoted[$key] = $this->quoteIdentifier($field_name);
            }
        }
        
//
        
$sql_query sprintf(
            
"ALTER TABLE %s ADD FULLTEXT %s (%s);"
            
,$this->quoteIdentifier($table_name)
            ,
strlen($index_name) ? $this->quoteIdentifier($index_name) : ""
            
,implode(","$fields_quoted)
        );
        
//
        
$dbresult   =   $this->ExtendedExecQuery($sql_query,false);
        
//
        
return $dbresult;
    }
    
    
/**
     * 
     * @param string $table_name
     * @param string $index_name
     * @param array $options
     * @return DBQueryResult
     */
    
function &dropIndexByName($table_name,$index_name,$options=array())
    {
        
// ALTER TABLE `VTatu_Artists` DROP INDEX `TextSearch_Index_Names_2`;
        //
        
$sql_query sprintf(
            
"ALTER TABLE %s  DROP INDEX %s;"
            
,$this->quoteIdentifier($table_name)
            ,
$this->quoteIdentifier($index_name)
        );
        
//
        
$dbresult   =   $this->ExtendedExecQuery($sql_query,false);
        
//
        
return $dbresult;
    }
    
    
    
    
    
    
    
    
    
    
/**
     * Получение информации о полях таблицы
     * 
     * SHOW COLUMNS FROM `UsersManagement_Authentication_Credentials`
     * SHOW FULL COLUMNS FROM `UsersManagement_Authentication_Credentials`
     * 
     * 
     *      [Field] => id
            [Type] => int(7)
            [Null] =>
            [Key] => PRI
            [Default] =>
            [Extra] => auto_increment
     *
     * @param string $tblName
     * @param string $dbName
     * @param string $full
     * @return array
     */
    
public function getFieldsList($tblName,$dbName=NULL,$full=true)
    {
        
//
        
$query sprintf(
            
$full "SHOW FULL COLUMNS FROM %s;" "SHOW COLUMNS FROM %s;"
            
,$this->quoteIdentifier($tblName)
        );
        
//
        
if($dbName !== NULL)
        {
            
$query sprintf(
                
$full "SHOW FULL COLUMNS FROM %s;" "SHOW COLUMNS FROM %s.%s;"
                
,$this->quoteIdentifier($dbName)
                ,
$this->quoteIdentifier($tblName)
            );
        }
        
        
$dbresult $this->ExtendedExecQuery($query);
        
        if(
$dbresult)
        {
            
$result   =   $dbresult->asArray(true);
        }
        
        
        
//$str = "";
        
        
foreach($result as $key => $value)
        {
            
//
            
if(!isset($result[$key]["TypeModificator"]))
            {
                
$result[$key]["TypeModificator"] = NULL;
            }
            
//
            
$result[$key]["FullType"] = $result[$key]["Type"];
            
//$result[$key]["Type"]     = NULL;
            //
            
$matches NULL;
            
//
            
if(preg_match("/^([^\(\)]*)\((.*)\)(.*)$/uis"$result[$key]["FullType"],$matches))
            {
                
$result[$key]["Type"]            = trim($matches[1]);
                
$result[$key]["TypeModificator"] = trim($matches[3]);
                
                
//$result[$key]["_"]["Type"]       = $value["FullType"];
                
                
                
if(!key_exists("Length"$value))
                {
                    
$result[$key]["Length"] = $matches[2];
                }
                
                
                
                
$result[$key]["."]              = $matches;
            }
            
//
        
}
        
//
        
return $result;
    }
    
    
    
    
    
    
    
    
    
    
/**
     * Проверка на наличие указаной БД на сервере
     * 
     * @param string $name
     * @param string $reset_cache
     * @return boolean
     */
    
function existsDB($name=NULL,$reset_cache=false)
    {
        static 
$dbs NULL;
        
        if(
$dbs === NULL OR $reset_cache)
        {
            
$dbs $this->getDBs();
        }
        
        if(
$name === NULL)
        {
            
$name =  $this->getDBName();
        }
        
        return 
in_array($name$dbs);
    }
    
    
/**
     * Исполнить запрос на создание базы данных
     *
     * @param string $db_name
     * @param boolean $if_not_exists
     * @return boolean
     */
    
function createDB($db_name='',$if_not_exists=true)
    {
        
$query  =   sprintf(
             
"CREATE DATABASE IF NOT EXISTS %s %s;"
            
,$this->quoteIdentifier($db_name)
            ,
'DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci'
        
);
        return 
$this->ExecQuery($query,false);
    }
    
/**
     * Получение числа записей в таблице выбранной базы данных
     *
     * @param string $db_tablename
     * @param string $db_name
     * @return integer
     */
    
public function getCountDBTableRecords ($db_tablename='',$db_name='')
    {
        
$result =   -1;
        
//
        
if(mb_strlen($db_name) < 1)
        {
            
$db_name      =   $this->getDBName();
        }
        
//
        
$query  =   sprintf(
            
"SELECT COUNT(*) as `num_count` FROM %s.%s;"
            
,$this->quoteIdentifier($db_name)
            ,
$this->quoteIdentifier($db_tablename)
        );
        
//
        //
        
$dbresult   =   $this->ExtendedExecQuery($query,false);
        
//
        
if($dbresult)
        {
            
$row_recordset  =   $dbresult->getCurrentRowRecordset(DBQueryResult::FETCH_MODE_ASSOC);
            
$result         =   $row_recordset["num_count"];
            
$dbresult->free();
        }
        
//
        
return $result;
    }
    
    
/**
     * Получение информации о таблицах базы данных
     *
     * @param string $dbname имя базы данных
     * @return array
     */
    
public function gatherTablesInfo($dbname="")
    {
        
$result =   array();
        
//
        
if(mb_strlen($dbname) < 1)
        {
            
$dbname      =   $this->getDBName();
        }
        
//
        
$query  =   sprintf("SHOW TABLE STATUS FROM %s;",$this->quoteIdentifier($dbname));
        
//
        
$dbresult   =   $this->ExtendedExecQuery($query,false);
        
//
        
if($dbresult)
        {
            while (
$row  =   $dbresult->getCurrentRowRecordset(DBQueryResult::FETCH_MODE_ASSOC))
            {
                
$result[$row['Name']] =   array();
                
$result[$row['Name']]['Name']         =   $row['Name'];
                
$result[$row['Name']]['Data_length']  =   $row['Data_length'];
                
$result[$row['Name']]['Index_length'] =   $row['Index_length'];
                
$result[$row['Name']]['Rows']         =   $row['Rows'];
            }
            
$dbresult->free();
        }
        
//
        
return $result;
    }
    
    
    
    
/**
     * Проверка наличия таблицы в активной базе данных
     *
     * @param string $table_name имя таблицы базы данных
     * @return boolean
     */
    
public function askTableExists ($table_name,$do_dbselect=true)
    {
        
$result =   NULL;
        
//
        
if(mb_strlen($table_name) < )
        {
            return 
$result;
        }
        
//
        
$query  =   sprintf("SHOW TABLES LIKE %s;",$this->quoteString($table_name));
        
//
        
$dbresult   =   $this->ExtendedExecQuery($query,$do_dbselect);
        
//
        
if($dbresult)
        {
            
$result $dbresult->getRowsCount();
            
$dbresult->free();
        }
        
//
        
return $result;
    }
    
    
/**
     * Проверка наличия базы данных на активном сервере
     *
     * @param string $dbname имя базы данных
     * @return boolean
     */
    
public function askDatabaseExists ($dbname)
    {
        
$result =   NULL;
        
//
        
if(mb_strlen($dbname) < 1)
        {
            return 
$result;
        }
        
//
        
$query  =   sprintf("SHOW DATABASES LIKE %s;",$this->quoteString($dbname));
        
//
        
$dbresult   =   $this->ExtendedExecQuery($query,false);
        
//
        
if($dbresult)
        {
            
$result $dbresult->getRowsCount();
            
$dbresult->free();
        }
        
//
        
return $result;
    }
    
    
    
    
    
    
    
    
    
    
    
/**
     * Проверка наличия таблицы в активной базе данных
     *
     * @param string $table_name имя таблицы базы данных
     * @return integer
     */
    
public function TableExists ($table_name,$do_dbselect=true)
    {
        if(!
$this->askTableExists($table_name,$do_dbselect))
        {
            
//return -1;
            
return false;
        }
        
//
        
return 1;
    }
    
    
    
/**
     * Проверка наличия базы данных на активном сервере
     *
     * @param string $dbname имя базы данных
     * @return integer
     */
    
public function DatabaseExists ($dbname)
    {
        if(
$this->askDatabaseExists($dbname))
        {
            return -
1;
        }
        
//
        
return 1;
    }
    
    
    
    
    
/**
     * Добавление нового поля в таблицу БД, если оно отсутствует
     *
     * @param string $tblName имя таблицы
     * @param string $clName имя добавляемого поля
     * @param string $clParams параметры добавляемого поля
     * @param string $PredclName имя поля передшествующего добавляемому
     * @return boolean
     */
    
public function addColumnIfItDoesNotExist($tblName,$clName,$clParams,$PredclName)
    {
        
$result NULL;
        
//
        
$query sprintf(
            
"SHOW COLUMNS FROM %s LIKE %s;"
            
,$this->quoteIdentifier($tblName)
            ,
$this->quoteString($clName)
        );
        
//
        
$dbresult   =   $this->ExtendedExecQuery($query,false);
        
//
        
if($dbresult)
        {
            
$exists $dbresult->getRowsCount();
            
$dbresult->free();
        }
        
//
        
        
if(!$exists)
        {
            
$query 
                 
"ALTER TABLE "." ".$this->quoteIdentifier($tblName)." "
                
."ADD COLUMN {$this->quoteIdentifier($clName)} {$clParams} "
                
."AFTER {$this->quoteIdentifier($PredclName)}"
                
.";"
            
;
            
$result_cmd $this->ExecQuery($query);
            if(!
$result_cmd)
            {
                
$result false;
            }
        }
        
//
        
return $result;
    }
    
    
    
    
    
/**
     * Переключиться на другую БД в текущем <b>подключении</b>
     *
     * Возвращает имя установленой БД
     *
     * @param string $db_name
     * @throws DBException
     * @return string
     */
    
function switchDB($db_name)
    {
        
$this->selectDB($db_name);
        
$this->dbName $db_name;
        
        return 
$this->dbName;
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
/**
     * Получить отчёт о текущем состоянии сервера
     *
     *
     * @param boolean $print
     * @return string
     */
    
function getServerStats($_format="struct",$print=false)
    {
        
        
$result    =  NULL;
        
//
        
$status explode('  'mysqli_stat($this->dbConnection));
        
//Returns a string with the status for uptime, threads, queries, open tables, flush tables and queries per second.
        // For a complete list of other status variables, you have to use the SHOW STATUS SQL command
        
switch(mb_strtolower($_format,"UTF-8"))
        {
            case 
"string" :
            {
                
$result    =  print_r($status,true);
                break;
            }
            case 
"array" :
            case 
"struct" :
            {
                
$result =   $status;
                break;
            }
        }
        
        return 
$result;
    }
    
    
    
    
    
    
    
    
/**
     * Получить отчёт о текущем состоянии сервера
     * 
     * @deprecated use getServerStats
     *
     * @param boolean $print
     * @return string
     */
    
function ServerStats($_format="struct",$print=false)
    {
        return 
$this->getServerStats($_format,$print);
    }
    
    
    
    
    
    
/**
     * Получить лог запросов
     *
     * @return MemoryLog
     */
    
function &getQueryLog()
    {
        return 
$this->_log;
    }
    
    
    
/**
     * Получить ссылку на логгер (SQL) запросов
     *
     * @todo: Написать логгер SQL запросов (запись в файл построчно, с сериализацией, каждого отдельного запроса. заголовок лога? (с отдалочной информацией, в т.ч. и по формату)
     *
     * @return MemoryLog
     */
    
function &getQueryLogger()
    {
    
        return 
$this->_log;
    }
    
    
    
    
/**
     * Формирование информации о выполныенных запросах в соответствии с указанным шаблоном
     * 
     * @deprecated
     *
     * @param string $_rec_tmpl шаблон строки информации о выполненносм запросе (формат sprintf, порядок: порядковый номер, время выполенения запроса, время затраченное на запрос, запрос)
     * @return string
     */
    
public function QueryLogAsText($_rec_tmpl=NULL)
    {
        
$_result =   '';
        
        if(
$_rec_tmpl === NULL)
        {
            
$_rec_tmpl "<br />[<strong>%s</strong>][%s][<strong>&Delta;=%s</strong>][%s]<br />";
        }
        
        
        
#
        #   Рендеринг данных
        #
        
$_data  =   $this->_log->GetRawData();
        
#
        #
        
foreach($_data as $record)
        {
            
$_result .= sprintf(
                
#"<br />[<strong>%s</strong>][%s][<strong>&Delta;=%s</strong>][%s]<br />"
                 
$_rec_tmpl
                
,$record['No']
                ,
$record['DateTime']
                ,
$record['delta']
                ,
$record['Query']
            );
        }
        
#
        #
        
return $_result;
    }
    
    
    
/**
     * Формирование информации о выполныенных запросах в соответствии с указанным шаблоном
     * 
     * @deprecated
     *
     * @param string $_rec_tmpl шаблон строки информации о выполненносм запросе (формат sprintf, порядок: порядковый номер, время выполенения запроса, время затраченное на запрос, запрос)
     * @return string
     */
    
public function renderQueryLog()
    {
        
$_result =   "";
        
//
        
$_data  =   $this->_log->getRawData();
        
//
        
$_result '<table class="table table-bordered table-striped table-hover">';
        
        foreach(
$_data as $record)
        {
            
$_result .= "<tr>";
            
            
$_result .= "<th>".$record['No']."</th>";
            
            
$_result .= "<td>".$record['DateTime']."</td>";
            
            
$_result .= "<td>[<strong>&Delta;=".$record['delta']."</strong>]</td>";
            
            
$_result .= "<td>".\SMC\HTML::TextAsHTML($record['Query'])."</td>";
            
            
$_result .= "</tr>";
        }
        
        
$_result "</table>";
        
//
        
return $_result;
    }
    
    
    
    
    
/**
     * Получить сводку о базе данных (хранилище/источнике)
     * 
     * 
     * @var array $exclude_tables
     * @return array
     */
    
function getSummary($exclude_tables=array())
    {
        
$result = array();
        
//
        
$result["Stats"] = array();
        
$result["Stats"]["nTables"]  = 0;
        
$result["Stats"]["nRecords"] = 0;
        
$result["Stats"]["DataSize"] = 0;
        
//
        
        
        
$DBResult $this->extendedExecQuery("SHOW TABLE STATUS;");
        
        
$tables_info $DBResult->asArray(true);
        
//
        
foreach ($tables_info as $data)
        {
            if(
in_array($data["Name"], $exclude_tables))
            {
                continue;
            }
            
            
$result["Stats"]["nTables"]++;
            
$result["Stats"]["nRecords"] += (double) $data["Rows"];
            
$result["Stats"]["DataSize"] += (double) $data["Data_length"];
        }
        
//
        
$result["Category"] = $this->getCategory();
        
$result["Type"]     = $this->getType();
        
$result["Server"]   = $this->getServerName();
        
$result["Name"]     = $this->getDBName();
        
//
        
$result["Role"]     = $this->getRole();
        
//
        
return $result;
    }
    
    
    
    
    
    
    
    
    
    
    
/**
     * PostgreSQL requires double quotes for identifier (SQL standard)
     * 
     * Both Oracle and MySQL let you use reserved words as object names by representing the name with a quoted identifier. However, MySQL allows some reserved words such as DATE and TIMESTAMP to be used as unquoted identifier for object names, although this is not allowed in Oracle.
     * SQL Developer appends an underscore (_) to the name of a MySQL object that is an Oracle reserved word.
     * 
     * //MySQL allows to use single and double quotes for data and for identifiers
     * //PostgreSQL requires single quotes for data (SQL standard)
     * 
     * @return string
     */
    
function getIdentifierQuotationCharacter()
    {
        switch (
$this->DB_TYPE)
        {
            case 
self::DB_TYPE_POSTGRESQL:
            {
                
// PostgreSQL requires double quotes for identifier (SQL standard)
                
return '"';
                break;
            }
            
            case 
self::DB_TYPE_MYSQL:
            case 
self::DB_TYPE_ORACLE:
            default:
            {
                
//Both Oracle and MySQL let you use reserved words as object names by representing the name with a quoted identifier. However, MySQL allows some reserved words such as DATE and TIMESTAMP to be used as unquoted identifier for object names, although this is not allowed in Oracle. SQL Developer appends an underscore (_) to the name of a MySQL object that is an Oracle reserved word.
                
return "`";
                break;
            }
        }
    }
    
    
    
    
    
    
    
    function 
real_escape_string($string)
    {
        return 
"'".$string."'";
    }
    
    function 
quote_string($value)
    {
        if(
$value === NULL)
        {
            
$value    =   "NULL";
        }
        else
        {
            
//$value    =   "'".$this->real_escape_string($value)."'";
            
$value    =   "".$this->real_escape_string($value)."";
        }
        
//
        
return $value;
    }
    
    
    
    
    
    
    function 
quoteIdentifier($value)
    {
        
$value    =   "`".$this->real_escape_string($value)."`";
        
        
//
        
return $value;
    }
    
    function 
quoteString($value)
    {
        if(
$value === NULL)
        {
            
$value    =   "NULL";
        }
        if(
$value === false)
        {
            
$value    =   0;
        }
        else
        {
            
$value    =   "'".$this->real_escape_string($value)."'";
        }
        
//
        
return $value;
    }
}

[Debug::Bugtrace] - не определена!

#0  __Shutdown_Decorator->renderErrorReport(Array ([type] => 1,[message] => Uncaught *{DB\Exception}:
[1114][The table 'Statistics_RequestJournal_Records' is full]

BD={MySQL}
SQL=[INSERT INTO 
		`Statistics_RequestJournal_Records` 
 (
		`ID`, 
		`GUID`, 
		`POUUID`, 
		`ClassName`, 
		`ParentGUID`, 
		`OwnerGUID`, 
		`timeCreated`, 
		`timeModified`, 
		`timeAccessed`, 
		`Description`, 
		`Comments`, 
		`CodeID`, 
		`VersionString`, 
		`Name`, 
		`Hash`, 
		`Order`, 
		`Active`, 
		`timeSynchronized`, 
		`Owner_GUID`, 
		`Owner_POUUID`, 
		`Owner_ClassName`, 
		`Owner_Active`, 
		`ParentObject_GUID`, 
		`ParentObject_POUUID`, 
		`ParentObject_ClassName`, 
		`ParentObject_VersionString`, 
		`Tags`, 
		`REQUEST_METHOD`, 
		`UNIQUE_ID`, 
		`RequestTime_Start`, 
		`HTTP_SCHEME`, 
		`HTTP_HOST`, 
		`HTTP_URL`, 
		`QUERY_STRING`, 
		`HTTP_REFERER`, 
		`HTTP_REFERER_HOST`, 
		`Request_Headers_JSON`, 
		`SessionID`, 
		`Client_IP`, 
		`Client_UserAgent`, 
		`Client_IsRobot`, 
		`Client_IsSearchEngineCrawler`, 
		`Client_IsVulnerabilityScanner`, 
		`Client_Robot_Type`, 
		`Client_Robot_Fami,[file] => /home/www-master/www/apps/HostSystem/SharedApps/moonlite13.cmf/core.moonlite13.ru/Modules/DBManagement/classes/class.DB_SQL.php,[line] => 654), html) called at [/home/www-master/www/vhosts/htdocs/preload.moonlite13.ru/.preload/classes/Processor.php:492]
#1  __Shutdown_Processor->_DislpayErrorReport(Array ([type] => 1,[message] => Uncaught *{DB\Exception}:
[1114][The table 'Statistics_RequestJournal_Records' is full]

BD={MySQL}
SQL=[INSERT INTO 
		`Statistics_RequestJournal_Records` 
 (
		`ID`, 
		`GUID`, 
		`POUUID`, 
		`ClassName`, 
		`ParentGUID`, 
		`OwnerGUID`, 
		`timeCreated`, 
		`timeModified`, 
		`timeAccessed`, 
		`Description`, 
		`Comments`, 
		`CodeID`, 
		`VersionString`, 
		`Name`, 
		`Hash`, 
		`Order`, 
		`Active`, 
		`timeSynchronized`, 
		`Owner_GUID`, 
		`Owner_POUUID`, 
		`Owner_ClassName`, 
		`Owner_Active`, 
		`ParentObject_GUID`, 
		`ParentObject_POUUID`, 
		`ParentObject_ClassName`, 
		`ParentObject_VersionString`, 
		`Tags`, 
		`REQUEST_METHOD`, 
		`UNIQUE_ID`, 
		`RequestTime_Start`, 
		`HTTP_SCHEME`, 
		`HTTP_HOST`, 
		`HTTP_URL`, 
		`QUERY_STRING`, 
		`HTTP_REFERER`, 
		`HTTP_REFERER_HOST`, 
		`Request_Headers_JSON`, 
		`SessionID`, 
		`Client_IP`, 
		`Client_UserAgent`, 
		`Client_IsRobot`, 
		`Client_IsSearchEngineCrawler`, 
		`Client_IsVulnerabilityScanner`, 
		`Client_Robot_Type`, 
		`Client_Robot_Fami,[file] => /home/www-master/www/apps/HostSystem/SharedApps/moonlite13.cmf/core.moonlite13.ru/Modules/DBManagement/classes/class.DB_SQL.php,[line] => 654), html, 1) called at [/home/www-master/www/vhosts/htdocs/preload.moonlite13.ru/.preload/classes/Processor.php:274]
#2  __Shutdown_Processor->shutdown(int)

Информация о данных текущего запроса


SERVER

Array
(
    [UNIQUE_ID] => ZtxdLorJsaoAACRWDkYAAAAM
    [CMF_ML13_MAIN_URL] => http://team.vtatu.com/
    [ml13_PathTo_HostSystem] => /home/www-master/www/apps/HostSystem
    [ml13_PathTo_SharedApps] => /home/www-master/www/apps/HostSystem/SharedApps/moonlite13.cmf/core.moonlite13.ru
    [ml13_SystemFilesLocationPath] => /home/www-master/www/apps/HostSystem/SharedApps/moonlite13.cmf/core.moonlite13.ru
    [CMF_ML13_SharedCoreMode] => 1
    [HTTPS] => on
    [SSL_TLS_SNI] => team.vtatu.com
    [SSL_SERVER_S_DN_CN] => team.vtatu.com
    [SSL_SERVER_I_DN_C] => US
    [SSL_SERVER_I_DN_O] => Let's Encrypt
    [SSL_SERVER_I_DN_CN] => R10
    [SSL_VERSION_INTERFACE] => mod_ssl/2.4.10
    [SSL_VERSION_LIBRARY] => OpenSSL/1.0.1t
    [SSL_PROTOCOL] => TLSv1.2
    [SSL_SECURE_RENEG] => true
    [SSL_COMPRESS_METHOD] => NULL
    [SSL_CIPHER] => ECDHE-RSA-AES256-GCM-SHA384
    [SSL_CIPHER_EXPORT] => false
    [SSL_CIPHER_USEKEYSIZE] => 256
    [SSL_CIPHER_ALGKEYSIZE] => 256
    [SSL_CLIENT_VERIFY] => NONE
    [SSL_SERVER_M_VERSION] => 3
    [SSL_SERVER_M_SERIAL] => 030E94B66574F6DC1CAFF862B35ECEC63733
    [SSL_SERVER_V_START] => Jun 28 20:19:47 2024 GMT
    [SSL_SERVER_V_END] => Sep 26 20:19:46 2024 GMT
    [SSL_SERVER_S_DN] => CN=team.vtatu.com
    [SSL_SERVER_I_DN] => CN=R10,O=Let's Encrypt,C=US
    [SSL_SERVER_A_KEY] => rsaEncryption
    [SSL_SERVER_A_SIG] => sha256WithRSAEncryption
    [SSL_SESSION_ID] => 8db94e0110ae85f7ab484f047527aeb02fb4f5026637a239ba0526edce257132
    [SSL_SESSION_RESUMED] => Initial
    [HTTP_USER_AGENT] => CCBot/2.0 (https://commoncrawl.org/faq/)
    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    [HTTP_ACCEPT_LANGUAGE] => en-US,en;q=0.5
    [HTTP_ACCEPT_ENCODING] => br,gzip
    [HTTP_HOST] => team.vtatu.com
    [HTTP_CONNECTION] => Keep-Alive
    [PATH] => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    [SERVER_SIGNATURE] => 
Apache/2.4.10 (Debian) Server at team.vtatu.com Port 443
[SERVER_SOFTWARE] => Apache/2.4.10 (Debian) [SERVER_NAME] => team.vtatu.com [SERVER_ADDR] => 95.217.151.145 [SERVER_PORT] => 443 [REMOTE_ADDR] => 98.82.120.188 [DOCUMENT_ROOT] => /home/www-master/www/vhosts/htdocs/team.vtatu.com [REQUEST_SCHEME] => https [CONTEXT_PREFIX] => [CONTEXT_DOCUMENT_ROOT] => /home/www-master/www/vhosts/htdocs/team.vtatu.com [SERVER_ADMIN] => [no address given] [SCRIPT_FILENAME] => /home/www-master/www/vhosts/htdocs/team.vtatu.com/index.php [REMOTE_PORT] => 45964 [GATEWAY_INTERFACE] => CGI/1.1 [SERVER_PROTOCOL] => HTTP/1.1 [REQUEST_METHOD] => GET [QUERY_STRING] => [REQUEST_URI] => / [SCRIPT_NAME] => /index.php [PHP_SELF] => /index.php [REQUEST_TIME_FLOAT] => 1725717806.128 [REQUEST_TIME] => 1725717806 )

GET

Array
(
)

POST

Array
(
)

FILES

Array
(
)

SESSION

Array
(
)

COOKIE

Array
(
)
[]