Что не так с моей логикой? Попытка сделать простой скрипт mysqli

Я пытаюсь создать 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:

Что не так с моей логикой? Попытка сделать простой скрипт mysqli

Скриншот столбца csgo и его формат:

Что не так с моей логикой? Попытка сделать простой скрипт mysqli

(если у пользователя никогда не было активной подписки, это будет NULL)

Обновлено: у меня нет ни одной синтаксической ошибки

or error конечно неправильно.
Dharman 24.07.2019 12:21
Предупреждение: Вы широко открыты для SQL-инъекции и действительно должны использовать параметризованный подготовленные заявления вместо создания запросов вручную. Они предоставляются ЗОП или MySQLi. Никогда не доверяйте никаким данным, особенно тем, которые исходят от клиента. Даже если ваши запросы выполняются только доверенными пользователями, вы все еще рискуете повредить свои данные.
Dharman 24.07.2019 12:22

@Dharman Это не так. Это собственная функция FluxBB. Он показывает ошибку вместо 500 страниц. В этом нет ничего плохого. Также не могли бы вы сказать мне, какая часть уязвима, ваш комментарий бесполезен, если вы не опишете его подробнее.

Motify 24.07.2019 12:22

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

Dharman 24.07.2019 12:23

@Dharman Уже есть mysqli_escape_realstring

Motify 24.07.2019 12:27

Его не следует использовать для предотвращения SQL-инъекций. Эта функция довольно бесполезна. Вы должны использовать подготовленные операторы, которые сделают ваш код безопасным и простым.

Dharman 24.07.2019 12:28

@Dharman Спасибо! Не могли бы вы привести один пример с подготовленными операторами в моем коде?

Motify 24.07.2019 12:30
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
7
46
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В этом фрагменте кода:

// 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.

Спасибо! Я не заметил там своей опечатки. Это все еще не работает. Я не знаком с запросами, содержащими «как», поэтому не могли бы вы дать мне ссылку на хороший учебник или сделать пример запроса здесь?

Motify 24.07.2019 12:33

Я бы изменил первый запрос на что-то вроде "SELECT sub FROM ".$db->prefix."keys` ГДЕ akey = '".$motify_akey."' AND used = '0'", and then use num_rows` в результате, чтобы проверить, что-то было однажды. Внутри вашего предложения if () вам не нужно запускать второй запрос, потому что у вас уже есть sub в объекте результатов из первого. Боюсь, я не могу ссылаться на учебники, попробуйте поэкспериментировать, чтобы получить зависание вещей.

droopsnoot 24.07.2019 12:42

Хорошо, поэтому я добавил эхо, если ключ недействителен или был использован. Он работает до тех пор, пока не проверит значение ключа (30, 90, 365). Я думаю, что проблема начинается отсюда `// проверить значение ключа (30 дней, 90 дней или 365 дней)`

Motify 24.07.2019 12:42

Затем, когда это сработает, прочитайте подготовленные операторы и измените их.

droopsnoot 24.07.2019 12:42

Вы заметили мое редактирование, где я говорю о том, как вернуть массив, а не плоскую переменную?

droopsnoot 24.07.2019 12:42

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

droopsnoot 24.07.2019 12:50

Разве этот запрос: $db->query("UPDATE ".$db->prefix."users` SET csgo = '".$new90)` не должен содержать предложение WHERE? Вы действительно хотите обновить каждую строку в таблице?

droopsnoot 24.07.2019 12:51

Другие вопросы по теме