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

Почему мы решили написать о выборе победителя? Это, наверно, самый важный вопрос для участников розыгрыша. Что поделать, действительно интересные (с профессиональной точки зрения) вопросы мало занимают проигравших участников. Им любопытно, почему кто-то другой получил джек-пот. Впрочем, это их законное право, так что не станем утаивать «секреты» работы. Однако просим их отнестись к нам с пониманием и снисхождением, ведь животрепещущий для них вопрос, оставляем «на десерт». А начнем мы все таки с базы данных.

База данных

Прежде всего, надо сказать о том, что сайт rosneft-promo.ru мы, как и все остальные наши сайты, сделали на замечательной (и бесплатной) платформе WordPress. Наверняка, крутые разработчики прочитывая это начнут обвинять нас в некомпетентности но товарищи… Ну правда, объясните мне, зачем использовать коммерческие движки там, где можно с огромным успехом (и экономией денег клиента) использовать бесплатные.

Ну, мы отвлеклись. Прежде всего, надо сказать то, что на сайте действительно происходил сбор заявок. Для этих целей была создана таблица «promo», которая потихонечку этими заявками пополнялась. Как видно из скриншота, в таблице были созданые достаточно типовые поля id, date (дата и время подачи заявки, для того, чтобы убрать те заявки, которые прийдут позже времени окончания приема заявок), code (собственно, промокод), fio, phone и email.

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

HTML, JS, CSS

В контенте на странице выбора победителя, мы можем выделить четыре тега, интересных для нас:

  • Тег P (Текст, в котором будет информация о победителе и его промокоде. ID: «winnar_name_code». По умолчанию скрыт через CSS display: none;)
  • Тег Input (Кнопка, по нажатию на которую происходит выборка победителя. ID: «winnar_button». По клику срабатывает функция winnar_get())
  • Тег Script (Скрипт, который содержит две функции: winnar_get и winnar_get_js)
  • Тег Style (CSS, описывающая внешний вид кнопки и текста)

Если внимательно посмотреть на листинг, то можно заметить, что функция winnar_get делает ajax запрос методом post к файлу winnar.php, а winnar_get_js выполняет код, полученный в результате этого ajax запроса.

Обратите внимание: заботясь о безопасности нашего сервера, мы заранее изменили название php файла, чтобы у специалистов из нашей отрасли не было соблазна экспериментировать ни с этим файлом ни с нашим сервером.

<p id="winnar_name_code"></p>

<input id="winnar_button" type="button" value="Выбрать победителя" name="select" OnClick="winnar_get();">

<script language="javascript">
function winnar_get()
{
$.post('/winnar.php', { submit: 'submit' },  winnar_get_js);
}
function winnar_get_js(data)
{
eval(data);
}
</script>

<style type="text/css">
#winnar_name_code {display: none; font-size: 3rem; text-align: center !important;}
#winnar_button {display: block; width: 25rem; padding: 2rem; background: #FDD400;     font-size: 2rem; margin: auto; transition: all 0.5s;}
#winnar_button:hover{background: #fff;}
</style>

PHP

А теперь, собственно, процесс выборки и вывода. Для наилучшего понимания аудиторией, мы немного переписали код и получили следующие функции:

  • init(): Нужна для того, чтобы объявить параметры соединения к БД ну и, собственно, само соединение
  • connect(): Проверка соединения на ошибки
  • counts(): Обращаемся к БД чтобы узнать, сколько записей вообще есть в таблице
  • random(): Узнаем, кто же собственно, победитель (Вот тут и происходит вся «Магия»)
  • result(): Обращаемся к БД чтобы узнать ФИО и промокод, возвращаем значение

А теперь, собственно, «то самое»: $Winnar = mt_rand(0, $Count);
Таким образом, становиться ясно, что победитель определяется с помощью генератора простых чисел на базе Вихря Мерсена! Важно отметить, что на сервере стоит PHP 7.1.3 а это значит, что mt_rand работает корректно, «по новому».

Обратите внимание: Значения $Database_Host, $Database_User, $Database_Pass мы, по вполне логичным причинам, не показываем.

Листинг

function init()
{
$Database_Host = "";
$Database_User = "";
$Database_Pass = "";
$Database_Base = "rosneft-promoru";
global $Database;
$Database = mysqli_connect($Database_Host, $Database_User, $Database_Pass, $Database_Base);
}

function connect()
{
global $Database;
if (mysqli_connect_errno())
{
echo "error";
exit;
}
if (!mysqli_set_charset($Database, "utf8"))
{
echo "error";
exit;
}
}

function counts()
{
global $Database, $Count;
if (isset($_POST['submit']))
{
$Query = "SELECT 'id' FROM promo";
if ($Result = mysqli_query($Database, $Query))
{
$Count = mysqli_num_rows($Result);
}
mysqli_free_result($Result);
}
}

function random()
{
global $Count, $Winnar;
$Winnar = mt_rand(0, $Count);
}

function result()
{
global $Database, $Winnar;
$Query = "SELECT code, fio FROM promo WHERE id = ".$Winnar;
if ($Result = mysqli_query($Database, $Query))
{
if (mysqli_num_rows($Result) > 0)
{
while ($Row = mysqli_fetch_assoc($Result))
{
$Content = "Победитель: ".$Row['fio']." (Промокод: ".$Row['code'].")";
echo "$('#winnar_name_code').html('".$Content."'); $('#winnar_name_code').fadeIn(5000, function() { });";
}
}
}
mysqli_free_result($Result);
}

init();
connect();
counts();
random();
result();

Итог

Ничего не поняли? Сожалеем, но подытожить постараемся по простому:

Из всего вышеописанного, можно понять, что общий алгоритм выбора победителя следующий:

  1. Собрать таблицу участников
  2. На странице выбора победителя, нажатие на кнопку «Выбрать победителя» вызывает скрипт
  3. Этот скрипт, делает асинхронный запрос к файлу на сервере
  4. Этот файл, подключается к базе данных
  5. Если при соединении нет ошибок, то
  6. Отправляется запрос к базе данных для определения общего количества участвующих промо-кодов
  7. Определяется победитель с помощью генератора простых чисел
  8. Отправляется запрос к базе данных для получения ФИО и промокода
  9. Полученная информация собирается в скрипт
  10. Скрипт передается как результат запроса обратно на страницу
  11. Скрипт запускается, заменяя и показывая содержимое скрытого текстового тега

Ну, и на последок, предлагаем ещё раз поздравить победителя с победой и пожелать ему всего самого лучшего!