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

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 случайные переменные, которые выводятся в браузере.
 

riff

Новичок
Научись дебажить...

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

// А здесь сессию никто не объявлял
...
$_SESSION['res_captcha'] = $a + $b;
 

cap4369

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

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

[name] => Вася [mail] => [email protected] [text] => text [captcha] => 10 [res_captcha] => 11 )
Как видно, сессионные переменные выводятся как надо. Только вот они не равны. То есть при отправке сообщения в переменную $_SESSION['res_captcha'] попадат новое значение, а в переменную $_SESSION['captcha'] попадает то, что я ввожу в поле input.
 
Последнее редактирование:

riff

Новичок
У тебя сессия стартует где-либо ещё, кроме как...
PHP:
if($_POST['submit']){
    session_start();  //<------ ...здесь
    //...
}
//
$a = mt_rand(1, 10);
$b = mt_rand(1, 10);
$_SESSION['res_captcha'] = $a + $b;
?
 

riff

Новичок
"В файле формы". А файл формы вызывается до или после этого файла? Ну, предположим что не после, тогда:
* инклюдится файл формы,
* в этом файле стартует сессия, но форма не распечатывается,
* затем инклюдится код из твоего сообщения,
* затем распечатывается форма,
так?.
 

cap4369

Новичок
Вот файл формы:
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();
?>
 

riff

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

---
<?=$_SESSION['text'];?> - точек с запятой не надо. Это не ответ, это просто так.
include "config.php"; инклюдится дважды. Это не ответ, это просто так.
а ещё, при первом вызове "файла формы", php должен выдавать "Notice. Undefined index:...", несколько штук, т.к. всякие <?=$_SESSION['name'];?> ещё не определены. Это не ответ, это просто так.
 
Последнее редактирование:

cap4369

Новичок
Этот скрипт отправки сообщений отлично работает. Единственная проблема - установка капчи и то, что include.php и в том и в другом файле так это только для того, чтобы указывать абсолютный путь к папкам при редиректе, если не подключать конфигурационный файл, абсолютный путь не читается, проверено. И точки с запятыми просто по привычке ставлю и в альтернативном синтаксисе, это тоже не критично. Не можешь помочь, так и скажи, я надеялся на конструктивную помощь.
 

riff

Новичок
Этот скрипт отправки сообщений отлично работает
То что скрипт отправки сообщений работает, я верю. Я ни слова про него не сказал.
Не можешь помочь, так и скажи, я надеялся на конструктивную помощь.
А какие результаты дало расставление проверок?
 

cap4369

Новичок
Я определился с проблемой, о ней я указывал выше. Она состоит в том, что при нажатии кнопки отправки сообщения, меняется сессионная переменная 'res_captcha', соответственно она становится не равной сессионной переменной "captcha", которой я для удобства вывода сообщений об ошибках или незаполненных полях присвоил значение $captcha, это видно в части скрипта if($_POST['submit']). Условие выполняется, соответственно выдается ошибка о неправильном ответе и сообщение не отправляется. И вот я все ломаю голову, как сделать так, чтобы то, что я ввожу в поле "input", т.е. сессионная переменная "captcha" была равной сессионной переменной "res_captcha" при нажатии на кнопку "submit". Все это видно по коду обработчика, только как решить эту проблему, я пока не знаю. И проверки тут не нужны, я сделал проверку - распечатал массив и в нем, переменные не равны, по указанным выше причинам.
 

riff

Новичок
После вывода формы ты данные в сессии стёр и саму её разрушил. Вот и всё - две твои последние строки.
 

cap4369

Новичок
Это тоже не причем, это сделано для того, чтобы при обновлении страницы, заполненные ранее поля очищались. Я специально ввел сессионные переменные"name", "email", "text" и занес их в значение "value" в "input" и "textarea", чтобы если поьзователь что- то сделал не так заполненные поля остались. Так что тут все правильно и сессию я уничтожил после отработки скрипта в самом конце. Если пользователь заполнил все поля и правильно ответил на вопрос, сообщение отправляется и поля очищаются. Еще раз повторюсь, дело не в сессиях, а в том, как я реализую сессионные переменные.
 

riff

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

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

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

Goto пункт 2...
 
Последнее редактирование:

cap4369

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

Вложения

riff

Новичок
Посетитель первый раз зашёл
начался скрипт
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

Vuzy

Новичок
riff, популярно объяснил.
Если убрать две последние строчки в скрипте должно работать. А для того что бы удалить данные их переменных текст и нейм. можно просто присвоить им пустые значения. или 0 или false
 

riff

Новичок
Vuzy У автора больше нет желания разговаривать. Чего зря стараешься? :)
 
Сверху