Я пытаюсь создать PHP-скрипт для своего форума FluxBB, который использует ключ активации, предоставленный пользователем, для их обновления и предоставления им активной подписки. Когда я нажимаю кнопку «активировать», ничего не происходит. Я предполагаю, что что-то не так с моей логикой, что это может быть?
Я пробовал несколько вещей, таких как изменение логики и упрощение кода, отладка. Но я застрял с этой проблемой.
if (isset($_POST['activate']))
{
// $pun_user['id'] is User ID
// csgo is subscription ending time
$motify_checksub = "SELECT `csgo` FROM `".$db->prefix."users` WHERE `id` = ".$pun_user['id'] or error('[Motify] Unable to check subscription', __FILE__, __LINE__, $db->error());
$db->query($motify_checksub);
$motify_sub_result = $db->fetch_assoc($motify_checksub);
$motify_now = date("Y-m-d H:i:s");
// has active subscription already?
if ($motify_sub_result > $motify_now)
{
$motify_akey = $db->escape($_POST['key']);
// check if activation key is valid and not used
$motify_check_key = $db->query("SELECT COUNT(*) FROM `".$db->prefix."keys` WHERE `akey` = '".$motify_akey."' AND `used` = '0'") or error('[Motify] Unable to validate activation key', __FILE__, __LINE__, $db->error());
$motify_key_result = $db->num_rows($motify_keycheck);
if ($motify_key_result > 0)
{
// check key value (30 days, 90 days or 365 days)
$motify_checklength = "SELECT `sub` FROM `".$db->prefix."keys` WHERE `akey` = '".$motify_akey or error('[Motify] Unable to subscription length', __FILE__, __LINE__, $db->error());
$db->query($motify_checklength);
$motify_length = $db->fetch_assoc($motify_checklength);
if ($motify_length == 30) // seems like this key gives 30 days subscription
{
// let's check when does this user's current subscription end
$motify_checkcsgo = "SELECT `csgo` FROM `".$db->prefix."users` WHERE `id` = '".$pun_user['id'] or error('[Motify] Unable to check current subscription time', __FILE__, __LINE__, $db->error());
$db->query($motify_checkcsgo);
$motify_csgo = $db->fetch_assoc($motify_checkcsgo);
// this key is used since now
$db->query("UDPATE `".$db->prefix."keys` SET `used` = '1' WHERE `akey` = '".$motify_akey) or error('[Motify] Unable to deactivate key', __FILE__, __LINE__, $db->error());
// let's add those days to his current subscription
$new30 = date("Y-m-d H:i:s", $motify_csgo + (24*3600*30));
$db->query("UPDATE `".$db->prefix."users` SET `csgo` = '".$new30) or error('[Motify] Unable to update subscription', __FILE__, __LINE__, $db->error());
$db->query("UDPATE `".$db->prefix."users` SET `group_id` = '5' WHERE `id` = '".$pun_user['id']) or error('[Motify] Unable to update group', __FILE__, __LINE__, $db->error());
redirect("https://example.com/forums/", "Your subscription has been successfully activated! Redirecting...");
}
if ($motify_length == 90) // seems like this key gives 90 days subscription
{
// let's check when does this user's current subscription end
$motify_checkcsgo = "SELECT `csgo` FROM `".$db->prefix."users` WHERE `id` = '".$pun_user['id'] or error('[Motify] Unable to check current subscription time', __FILE__, __LINE__, $db->error());
$db->query($motify_checkcsgo);
$motify_csgo = $db->fetch_assoc($motify_checkcsgo);
// this key is used since now
$db->query("UDPATE `".$db->prefix."keys` SET `used` = '1' WHERE `akey` = '".$motify_akey) or error('[Motify] Unable to deactivate key', __FILE__, __LINE__, $db->error());
// let's add those days to his current subscription
$new90 = date("Y-m-d H:i:s", $motify_csgo + (24*3600*90));
$db->query("UPDATE `".$db->prefix."users` SET `csgo` = '".$new90) or error('[Motify] Unable to update subscription', __FILE__, __LINE__, $db->error());
$db->query("UDPATE `".$db->prefix."users` SET `group_id` = '5' WHERE `id` = '".$pun_user['id']) or error('[Motify] Unable to update group', __FILE__, __LINE__, $db->error());
redirect("https://example.com/forums/", "Your subscription has been successfully activated! Redirecting...");
}
if ($motify_length == 365) // seems like this key gives 1 year subscription
{
// let's check when does this user's current subscription end
$motify_checkcsgo = "SELECT `csgo` FROM `".$db->prefix."users` WHERE `id` = '".$pun_user['id'] or error('[Motify] Unable to check current subscription time', __FILE__, __LINE__, $db->error());
$db->query($motify_checkcsgo);
$motify_csgo = $db->fetch_assoc($motify_checkcsgo);
// this key is used since now
$db->query("UDPATE `".$db->prefix."keys` SET `used` = '1' WHERE `akey` = '".$motify_akey) or error('[Motify] Unable to deactivate key', __FILE__, __LINE__, $db->error());
$new365 = date("Y-m-d H:i:s", $motify_csgo + (24*3600*365));
// let's add those days to his current subscription
$db->query("UPDATE `".$db->prefix."users` SET `csgo` = '".$new365) or error('[Motify] Unable to update subscription', __FILE__, __LINE__, $db->error());
// upgrading user to premium group
$db->query("UDPATE `".$db->prefix."users` SET `group_id` = '5' WHERE `id` = '".$pun_user['id']) or error('[Motify] Unable to update group', __FILE__, __LINE__, $db->error());
redirect("https://example.com/forums/", "Your subscription has been successfully activated! Redirecting...");
}
}
}
// expired or no subscription at all
else
{
// this has same logic as above one but this user doesn't have active subscription already or it has been expired
$motify_akey = $db->escape($_POST['key']);
$motify_check_key = $db->query("SELECT COUNT(*) FROM `".$db->prefix."keys` WHERE `akey` = '".$motify_akey."' AND `used` = '0'") or error('[Motify] Unable to validate activation key', __FILE__, __LINE__, $db->error());
$db->query($motify_key_check);
$motify_key_result = $db->num_rows($motify_keycheck);
if ($motify_key_result > 0)
{
$motify_checklength = "SELECT `sub` FROM `".$db->prefix."keys` WHERE `akey` = '".$motify_akey or error('[Motify] Unable to subscription length', __FILE__, __LINE__, $db->error());
$db->query($motify_checklength);
$motify_length = $db->fetch_assoc($motify_checklength);
if ($motify_length == 30)
{
$db->query("UDPATE `".$db->prefix."keys` SET `used` = '1' WHERE `akey` = '".$motify_akey) or error('[Motify] Unable to deactivate key', __FILE__, __LINE__, $db->error());
$new30 = date("Y-m-d H:i:s", $motify_csgo (24*3600*30));
$db->query("UPDATE `".$db->prefix."users` SET `csgo` = '".$new30) or error('[Motify] Unable to update subscription', __FILE__, __LINE__, $db->error());
$db->query("UDPATE `".$db->prefix."users` SET `group_id` = '5' WHERE `id` = '".$pun_user['id']) or error('[Motify] Unable to update group', __FILE__, __LINE__, $db->error());
redirect("https://example.com/forums/", "Your subscription has been successfully activated! Redirecting...");
}
if ($motify_length == 90)
{
$db->query("UDPATE `".$db->prefix."keys` SET `used` = '1' WHERE `akey` = '".$motify_akey) or error('[Motify] Unable to deactivate key', __FILE__, __LINE__, $db->error());
$new90 = date("Y-m-d H:i:s", $motify_csgo (24*3600*90));
$db->query("UPDATE `".$db->prefix."users` SET `csgo` = '".$new90) or error('[Motify] Unable to update subscription', __FILE__, __LINE__, $db->error());
$db->query("UDPATE `".$db->prefix."users` SET `group_id` = '5' WHERE `id` = '".$pun_user['id']) or error('[Motify] Unable to update group', __FILE__, __LINE__, $db->error());
redirect("https://example.com/forums/", "Your subscription has been successfully activated! Redirecting...");
}
if ($motify_length == 365)
{
$db->query("UDPATE `".$db->prefix."keys` SET `used` = '1' WHERE `akey` = '".$motify_akey) or error('[Motify] Unable to deactivate key', __FILE__, __LINE__, $db->error());
$new365 = date("Y-m-d H:i:s", $motify_csgo (24*3600*365));
$db->query("UPDATE `".$db->prefix."users` SET `csgo` = '".$new365) or error('[Motify] Unable to update subscription', __FILE__, __LINE__, $db->error());
$db->query("UDPATE `".$db->prefix."users` SET `group_id` = '5' WHERE `id` = '".$pun_user['id']) or error('[Motify] Unable to update group', __FILE__, __LINE__, $db->error());
redirect("https://example.com/forums/", "Your subscription has been successfully activated! Redirecting...");
}
}
}
}
<!-- HTML part -->
<form method = "POST">
<div class = "inform">
<input type = "hidden" name = "form_sent" value = "1">
<fieldset>
<div class = "infldset">
<input type = "text" maxlength = "35" name = "key" placeholder = "Activation key" required>
<input type = "submit" name = "activate" value = "Activate">
</div>
</fieldset>
</div>
</form>
Скриншот таблицы keys:
Скриншот столбца csgo и его формат:
(если у пользователя никогда не было активной подписки, это будет NULL)
Обновлено: у меня нет ни одной синтаксической ошибки
@Dharman Это не так. Это собственная функция FluxBB. Он показывает ошибку вместо 500 страниц. В этом нет ничего плохого. Также не могли бы вы сказать мне, какая часть уязвима, ваш комментарий бесполезен, если вы не опишете его подробнее.
В этом много неправильного. Самая большая проблема заключается в том, что строка никогда не будет ложной.
@Dharman Уже есть mysqli_escape_realstring
Его не следует использовать для предотвращения SQL-инъекций. Эта функция довольно бесполезна. Вы должны использовать подготовленные операторы, которые сделают ваш код безопасным и простым.
@Dharman Спасибо! Не могли бы вы привести один пример с подготовленными операторами в моем коде?






В этом фрагменте кода:
// check if activation key is valid and not used
$motify_check_key = $db->query("SELECT COUNT(*) FROM `".$db->prefix."keys` WHERE `akey` = '".$motify_akey."' AND `used` = '0'") or error('[Motify] Unable to validate activation key', __FILE__, __LINE__, $db->error());
$motify_key_result = $db->num_rows($motify_keycheck);
if ($motify_key_result > 0)
откуда $motify_keycheck в вашей предпоследней строке? Разве так не должно быть $motify_check_key? Но тогда, если это так, num_rows всегда будет 1, потому что вы возвращаете счетчик. Поэтому вместо этого вы хотите получить переменную count (поэтому дайте ей имя в запросе, используя 'as') и посмотрите на ее значение.
Поскольку ваш следующий запрос затем возвращается к той же таблице, чтобы получить другой столбец, вам лучше объединить их.
В этом бите:
$motify_length = $db->fetch_assoc($motify_checklength);
if ($motify_length == 30) // seems like this key gives 30 days subscription
$motify_length — это ассоциативный массив, поэтому он никогда не будет равен 30. Вместо этого вы должны проверять $motify_length['sub']. Та же проблема с этими двумя:
$motify_csgo = $db->fetch_assoc($motify_checkcsgo);
...
$new30 = date("Y-m-d H:i:s", $motify_csgo + (24*3600*30));
Я не понимаю, как вы не получаете ошибок, когда пытаетесь выполнять такие операции с полными массивами. Здесь поможет простая отладка с использованием var_dump и echo.
Спасибо! Я не заметил там своей опечатки. Это все еще не работает. Я не знаком с запросами, содержащими «как», поэтому не могли бы вы дать мне ссылку на хороший учебник или сделать пример запроса здесь?
Я бы изменил первый запрос на что-то вроде "SELECT sub FROM ".$db->prefix."keys` ГДЕ akey = '".$motify_akey."' AND used = '0'", and then use num_rows` в результате, чтобы проверить, что-то было однажды. Внутри вашего предложения if () вам не нужно запускать второй запрос, потому что у вас уже есть sub в объекте результатов из первого. Боюсь, я не могу ссылаться на учебники, попробуйте поэкспериментировать, чтобы получить зависание вещей.
Хорошо, поэтому я добавил эхо, если ключ недействителен или был использован. Он работает до тех пор, пока не проверит значение ключа (30, 90, 365). Я думаю, что проблема начинается отсюда `// проверить значение ключа (30 дней, 90 дней или 365 дней)`
Затем, когда это сработает, прочитайте подготовленные операторы и измените их.
Вы заметили мое редактирование, где я говорю о том, как вернуть массив, а не плоскую переменную?
Почему у вас есть эти отдельные блоки кода для разной продолжительности подписки? Вы уже получаете длину из таблицы ключей активации, почему бы не использовать ее в расчетах вместо всего этого дополнительного кода?
Разве этот запрос: $db->query("UPDATE ".$db->prefix."users` SET csgo = '".$new90)` не должен содержать предложение WHERE? Вы действительно хотите обновить каждую строку в таблице?
or errorконечно неправильно.