Не правильная проверка сессионных переменных

  • Автор темы Автор темы cap4369
  • Дата начала Дата начала

cap4369

Новичок
Здравствуйте!
Сделал форму обратной связи с математической проверкой спама. Однако при проверке сессионных переменных выдается ошибка о неправильном ответе. При распечатке массива $_SESSION после нажатия кнопки выводится:
Array(
[captcha] => 9
[res_captcha] => 19
),
то есть при нажатии кнопки отправки сообщения меняется сессионная переменная $_SESSION['captcha'] и результат введенный мной в поле input естественно уже не равен новому значению. Помогите разобраться как сделать так, чтобы при отправке сообщения сессионные переменные оставались равными.
PHP:
<?php
include "config.php";

if($_POST['submit']){
    session_start();
// определяем переменные
    $name = substr($_POST['name'], 0, 20);
    $mail = substr($_POST['mail'], 0, 20);
    $text = substr($_POST['text'], 0, 2000);
    $captcha = $_POST['captcha'];
  
// проверка заполнения обязательных полей  
    $error = '';
    $pattern = "/^.+@[a-z0-9]+\.[a-z]{2,6}$/i";
    if(empty($name)) $error = '<li>Не заполнено поле "Имя"</li>';
    if(empty($mail)) $error .= '<li>Не заполнено поле "Email"</li>';
    if(empty($text)) $error .= '<li>Не заполнено поле "Сообщение"</li>';
    if(empty($captcha)) $error .= '<li>Не заполнено поле "Введите ответ"</li>';
    if(!empty($mail) and !preg_match($pattern, $mail)) $error .= '<li>Поле "Ваш Email:" не соответствует установленному формату</li>';
    if($captcha != $_SESSION['res_captcha']) $error .= '<li>Ответ на вопрос неверный</li>';

    if(empty($error)) {
// определяем переменные
        $to = '[email protected]';
        $subject = "\r\n".'Заполнена форма на сайте'. "\r\n";
        $message = "\r\n"."Имя: " .$name. "\r\n";
        $message .= "Обратный e-mail: " .$mail. "\r\n";
        $message .= "Текст сообщения: " .$text. "\r\n";
        $headers = "Content-type: text/plain; charset = \"utf-8\"";
// формируем сообщение
        if(mail($to, $subject, $message, $headers)) {
            $_SESSION['res'] = $name.', Ваше письмо успешно отправлено.';
            header("Location: $site_url?option=contacts");
            exit();
        }
        else {
            $_SESSION['res'] = 'Произошла ошибка. Попробуйте еще раз.';
            header("Location: $site_url?option=contacts");
            exit();
        }
    }
    else {
        $_SESSION['res'] = "<strong>Не заполнены обязательные поля или допущены ошибки:</strong><ul>" .$error. "</ul>";
        $_SESSION['name'] = $name;
        $_SESSION['mail'] = $mail;
        $_SESSION['text'] = $text;
        $_SESSION['captcha'] = $captcha;
        header("Location: $site_url?option=contacts");
        exit();
    }
    header("Location: $site_url?option=contacts");
    exit();    
}
// Определение переменных для капчи
$a = mt_rand(1, 10);
$b = mt_rand(1, 10);
$_SESSION['res_captcha'] = $a + $b;
?>
Здесь $a и $b случайные переменные, которые выводятся в браузере.
 
Научись дебажить...

PHP:
if($_POST['submit']){
    session_start();
    //всё что здесь, знает что такое $_SESSION
}

// А здесь сессию никто не объявлял
...
$_SESSION['res_captcha'] = $a + $b;
 
Не в этом дело. Я распечатываю значения $_SESSION и они в браузере выводятся как надо:
Код:
Array ( [res] => Не заполнены обязательные поля или допущены ошибки:

    Ответ на вопрос неверный

[name] => Вася [mail] => [email protected] [text] => text [captcha] => 10 [res_captcha] => 11 )
Как видно, сессионные переменные выводятся как надо. Только вот они не равны. То есть при отправке сообщения в переменную $_SESSION['res_captcha'] попадат новое значение, а в переменную $_SESSION['captcha'] попадает то, что я ввожу в поле input.
 
Последнее редактирование:
У тебя сессия стартует где-либо ещё, кроме как...
PHP:
if($_POST['submit']){
    session_start();  //<------ ...здесь
    //...
}
//
$a = mt_rand(1, 10);
$b = mt_rand(1, 10);
$_SESSION['res_captcha'] = $a + $b;
?
 
"В файле формы". А файл формы вызывается до или после этого файла? Ну, предположим что не после, тогда:
* инклюдится файл формы,
* в этом файле стартует сессия, но форма не распечатывается,
* затем инклюдится код из твоего сообщения,
* затем распечатывается форма,
так?.
 
Вот файл формы:
PHP:
<?php
    include "config.php";
    session_start();
    include "mail.php";//Отладчик инклюдится для вывода капчи
    print_r($_SESSION);// Для проверки   
?>

<div class="form_mail">
    <form method="post" action="<?php echo $site_url; ?>classes/mail.php">
        <table cellspacing="20">
            <tr>
                <td><span id="red_star">*</span> Имя:</td>
                <td><span><input type="text" name="name" maxlength="20" size="25" value="<?=$_SESSION['name'];?>" /></span></td>
            </tr>
            <tr>
                <td><span id="red_star">*</span> Ваш Email:</td>
                <td><span><input type="text" name="mail" maxlength="20" size="25" value="<?=$_SESSION['mail'];?>" /></span></td>
            </tr>
            <tr>
                <td>
                <span id="red_star">*</span> Сообщение:</td>
                <td><span><textarea cols="45" rows="5" name="text"><?=$_SESSION['text'];?></textarea></span></td>
            </tr>           
                <tr>
                    <td>Введите ответ: <br /><h3><?=$a?> + <?=$b?> = ?</h3></td>
                   
                    <td><span><input type = "text" name = "captcha" /></span></td>
                </tr>
           
            <tr>
                <td colspan="2"><p class="form_mail_submit"><input  type="submit" name="submit" value="Отправить сообщение"></p></td>
            </tr>
        </table>           
    </form>
    <p class="message"><?=$_SESSION['res']?><p>
</div><!-- #mailform -->
<?php
session_unset();
session_destroy();
?>
 
Мужык, ты чо, издеваешься? Неужели в этом файле ты не заметил ничего подозрительного?
Ну не умеешь ты дебажить, так наставь проверок на каждой строке и найди где меняется значение.

---
<?=$_SESSION['text'];?> - точек с запятой не надо. Это не ответ, это просто так.
include "config.php"; инклюдится дважды. Это не ответ, это просто так.
а ещё, при первом вызове "файла формы", php должен выдавать "Notice. Undefined index:...", несколько штук, т.к. всякие <?=$_SESSION['name'];?> ещё не определены. Это не ответ, это просто так.
 
Последнее редактирование:
Этот скрипт отправки сообщений отлично работает. Единственная проблема - установка капчи и то, что include.php и в том и в другом файле так это только для того, чтобы указывать абсолютный путь к папкам при редиректе, если не подключать конфигурационный файл, абсолютный путь не читается, проверено. И точки с запятыми просто по привычке ставлю и в альтернативном синтаксисе, это тоже не критично. Не можешь помочь, так и скажи, я надеялся на конструктивную помощь.
 
Этот скрипт отправки сообщений отлично работает
То что скрипт отправки сообщений работает, я верю. Я ни слова про него не сказал.
Не можешь помочь, так и скажи, я надеялся на конструктивную помощь.
А какие результаты дало расставление проверок?
 
Я определился с проблемой, о ней я указывал выше. Она состоит в том, что при нажатии кнопки отправки сообщения, меняется сессионная переменная 'res_captcha', соответственно она становится не равной сессионной переменной "captcha", которой я для удобства вывода сообщений об ошибках или незаполненных полях присвоил значение $captcha, это видно в части скрипта if($_POST['submit']). Условие выполняется, соответственно выдается ошибка о неправильном ответе и сообщение не отправляется. И вот я все ломаю голову, как сделать так, чтобы то, что я ввожу в поле "input", т.е. сессионная переменная "captcha" была равной сессионной переменной "res_captcha" при нажатии на кнопку "submit". Все это видно по коду обработчика, только как решить эту проблему, я пока не знаю. И проверки тут не нужны, я сделал проверку - распечатал массив и в нем, переменные не равны, по указанным выше причинам.
 
После вывода формы ты данные в сессии стёр и саму её разрушил. Вот и всё - две твои последние строки.
 
Это тоже не причем, это сделано для того, чтобы при обновлении страницы, заполненные ранее поля очищались. Я специально ввел сессионные переменные"name", "email", "text" и занес их в значение "value" в "input" и "textarea", чтобы если поьзователь что- то сделал не так заполненные поля остались. Так что тут все правильно и сессию я уничтожил после отработки скрипта в самом конце. Если пользователь заполнил все поля и правильно ответил на вопрос, сообщение отправляется и поля очищаются. Еще раз повторюсь, дело не в сессиях, а в том, как я реализую сессионные переменные.
 
Стартует(=создаётся) новая сессия.
Генерится "капча".
Выводится форма, (данные заполняются из пустот = notice...).
Уничтожается сессия (со всеми данными).

Нажимаешь кнопку отправить.
Стартует(=создаётся) новая сессия.
С пустотой сверяется введённое значение капчи. = не совпадает.
Данные записываются в сессию.
Перебрасывает, как я понял, опять на форму.

Стартует существующая сессия.
Генерится "капча".
Выводится форма, данные заполняются из сохранённой сессии.
Уничтожается сессия (со всеми данными).

Goto пункт 2...
 
Последнее редактирование:
Нет, при старте сессии в нее уже попадает значение res_captcha, так как она определена переменными $a и $b и равна их сумме. Остальные сессионные переменные формируются после нажатия кнопки и ЕСЛИ ВСЕ НОРМАЛЬНО ПОСЛЕ ОТПРАВКИ СООБЩЕНИЯ УНИЧТОЖАЮТСЯ. А если пользователь что- то сделал не так, сообщение не отправляется, соответственно сессия сохраняется и заполненные поля остаются заполненными, но при этом меняется капча. Пуcтота там никак не получается, так как пользователь вводит данные. Смотри мои скриншоты.
 

Вложения

  • screen1.jpg
    screen1.jpg
    52,7 KB · Просмотры: 6
  • screen2.jpg
    screen2.jpg
    745,8 KB · Просмотры: 5
Посетитель первый раз зашёл
начался скрипт
PHP:
<?php
    //...
    session_start(); //новая сессия. $_SESSION пустая.
    include "mail.php";//Заполняем $_SESSION['res_captcha'] = 4+4=8
    print_r($_SESSION);// выводит как на первом скриншоте
?>

<div class="form_mail">
    <form method="post">
           ........... выводишь форму ...............
           и здесь, кстати, ты должен получать notices
           так как обращаешься к $_SESSION['name'] и т.п.
           о том что их нет, ты можешь понять по первому скриншоту.
    </form>
</div>
<?php
session_unset();
session_destroy(); //уничтожаешь сессию вместе с $_SESSION['res_captcha']
?>
закончился скрипт

нажимаешь отправить в форме

начался скрипт
PHP:
<?php
include "config.php";

if($_POST['submit']){
    session_start(); ////новая сессия. $_SESSION пустая. потому что ты ее выше уничтожил
    //print_r($_SESSION);// выдала бы тебе пустоту
    //......
    if($captcha != $_SESSION['res_captcha'])
            $error .= '<li>Ответ на вопрос неверный</li>'; //нет такой $_SESSION['res_captcha']

    if(empty($error)) {
             //...............
    }
    else {
        $_SESSION['name'] = $name; //сохраняешь введённые пользователем данные
        $_SESSION['mail'] = $mail;
        $_SESSION['text'] = $text;
        $_SESSION['captcha'] = $captcha; //сюда ты вписываешь те самые 8
        header("Location: $site_url?option=contacts");
        exit();
    }
?>
закончился скрипт

тебя перекинуло на скрипт с формой

начался скрипт
PHP:
<?php
    //...
    session_start(); //старт существующей сессии, как и положено НЕ пустая
    include "mail.php";//Заполняем $_SESSION['res_captcha'] новым значением 7+8=15
    print_r($_SESSION);// выводит как на втором скриншоте
?>

<div class="form_mail">
    <form method="post">
        ........... выводишь форму ...............
        а здесь $_SESSION['name'] и т.п. существуют
    </form>
</div>
<?php
session_unset();
session_destroy(); //уничтожаешь сессию вместе с новым значением $_SESSION['res_captcha']
?>
закончился скрипт

нажимаешь отправить в форме... всё повторяется.
 
Последнее редактирование:
  • Like
Реакции: Vuzy
riff, популярно объяснил.
Если убрать две последние строчки в скрипте должно работать. А для того что бы удалить данные их переменных текст и нейм. можно просто присвоить им пустые значения. или 0 или false
 
Vuzy У автора больше нет желания разговаривать. Чего зря стараешься? :)
 
riff, но мне... хотелось поговорить... а он...
a2oLPQTuOMg.jpg
 
Сверху