【问题标题】:CAPTCHA Not Validating Properly验证码未正确验证
【发布时间】:2017-03-24 08:40:09
【问题描述】:

我正在处理一个表单,除了自定义验证码之外,一切似乎都运行良好。无论我输入错误的答案还是实际正确的答案,表单都不会提交到数据库,并使用我的“请重试”错误消息重新加载表单...我希望该字段的验证遵循相同的格式和其他人一样,但不知道这是否可能(这是验证部分中的 $captchaValid )。这是我的表单中的 php 代码:

<?php   
//captcha
session_start();
$digit1 = mt_rand(1, 10);
$digit2 = mt_rand(1, 10);

$math ="$digit1 + $digit2";
$_SESSION['answer'] = $digit1 + $digit2;

//error reporting
error_reporting(E_ALL);
ini_set('display_errors','1');

//include validation file here!!
include_once('validationresult.php');

//results
$firstnameValid = new ValidationResult("", "", "", true);
$lastnameValid  = new ValidationResult("", "", "", true);
$emailValid = new ValidationResult("", "", "", true);
$captchaValid = new ValidationResult("", "", "", true);

//validation
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $firstnameValid = ValidationResult::checkParameter("firstname", '/^[a-zA-Z ]*$/', 'Only Letters and Spaces Allowed');
    $lastnameValid = ValidationResult::checkParameter("lastname", '/^[a-zA-Z ]*$/', 'Only Letters and Spaces Allowed');
    $emailValid = ValidationResult::checkParameter("email", '/(.+)@([^\.].*)\.([a-z]{2,})/', 'Please enter valid e-mail');
    $captchaValid = ValidationResult::checkParameter("captcha", $_SESSION['answer'] == $_POST['answer'], 'Please try again');
//redirection

if ($firstnameValid->isValid() && $lastnameValid->isValid() && $emailValid->isValid() && $captchaValid->isValid() ) {
    require "connectiontest.php";
    header('Location: thankyou.html');
    exit;
    }
}


?>

以下是我单独的验证文件:

<?php 

class ValidationResult
{
    private $value;
    private $cssClassName;
    private $errorMessage;
    private $isValid = true;


    function __construct($cssClassName, $value, $errorMessage, $isValid)
    {
        $this->cssClassName = $cssClassName;
        $this->value = $value;
        $this->errorMessage = $errorMessage;
        $this->isValid = $isValid;
    }

    public function getCssClassName() { return $this->cssClassName;}
    public function getValue() { return $this->value;}
    public function getErrorMessage() { return $this->errorMessage;}
    public function isValid() { return $this->isValid;}

    static public function checkParameter($queryName, $pattern, $errMsg) {
        $error = "";
        $errClass = "";
        $value = "";
        $isValid = "true";

        if (empty($_POST[$queryName])) {
            $error = $errMsg;
            $errClass = "error";
            $isValid = false;
        }
        else {
            $value = $_POST[$queryName];
            if ( ! preg_match($pattern, $value) ) {
                $error = $errMsg;
                $errClass = "error";
                $isValid = false;
            }
        }
        return new ValidationResult($errClass, $value, $error, $isValid);
    }
}

 ?>

我试过改变这部分:

$captchaValid = ValidationResult::checkParameter("captcha", $_SESSION['answer'] == $_POST['answer'], 'Please try again');

几种不同的方法来看看我是否可以让它工作,但正如我所说,我什至不知道这是否可能(因为它不是真正的正则表达式?)。我尝试删除 "==$_POST..." 部分,将其括在单引号和双引号中,等等,要么得到错误,要么得到与以前相同的结果。如果无法实现我想要的,我感谢有关替代解决方案的建议...

一些注意事项:我是非常 php 新手,对任何事情都不太了解,所以请记住这一点。 另外,我还不知道javascript(在这种情况下并不重要)。 HTML、CSS 和 PHP 是关于我知识的广度。这是为了学校作业。

编辑 这是完整的代码,其中包含包含表单的 html。根据之前的建议进行了一些修改:

<?php   
//captcha
if (!isset($_SESSION['answer'])) {
    $digit1 = mt_rand(1, 10);
    $digit2 = mt_rand(1, 10);

    $math ="$digit1 + $digit2";
    $_SESSION['answer'] = $digit1 + $digit2;
}


//error reporting
error_reporting(E_ALL);
ini_set('display_errors','1');

//include validation file here!!
include_once('validationresult.php');

//results
$firstnameValid = new ValidationResult("", "", "", true);
$lastnameValid  = new ValidationResult("", "", "", true);
$emailValid = new ValidationResult("", "", "", true);
$captchaValid = new ValidationResult("", "", "", true);

//validation
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $firstnameValid = ValidationResult::checkParameter("firstname", '/^[a-zA-Z ]*$/', 'Only Letters and Spaces Allowed');
    $lastnameValid = ValidationResult::checkParameter("lastname", '/^[a-zA-Z ]*$/', 'Only Letters and Spaces Allowed');
    $emailValid = ValidationResult::checkParameter("email", '/(.+)@([^\.].*)\.([a-z]{2,})/', 'Please enter valid e-mail');
    $captchaValid = ValidationResult::checkParameter("captcha", "/" .  $_POST['answer'] . "/" , 'Please try again');

    //redirection

    if ($firstnameValid->isValid() && $lastnameValid->isValid() && $emailValid->isValid() && $captchaValid->isValid() ) {
        require "connectiontest.php";
        header('Location: thankyou.html');
        exit;
    }
}


?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Registration</title>
</head>

<body>

    <form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>" >

        <?php echo $firstnameValid->getCssClassName(); ?>
        <label for="firstname">First name:</label> <input type="text" name="firstname"  value="<?php echo $firstnameValid->getValue(); ?>" required> <br>
        <span class="help-inline" id="errorFirstname"> <?php echo $firstnameValid->getErrorMessage(); ?> </span> <br>

        <?php echo $lastnameValid->getCssClassName(); ?>
        <label for="lastname">Last name:</label> <input type="text" name="lastname" value="<?php echo $lastnameValid->getValue(); ?>" required> <br>
        <span class="help-inline" id="errorLastname"> <?php echo $lastnameValid->getErrorMessage(); ?> </span> <br>


        <?php echo $emailValid->getCssClassName(); ?>
        <label for="email">E-mail:</label> <input type="email" name="email" value="<?php echo $emailValid->getValue(); ?>" required> <br>
        <span class="help-inline" id="errorEmail"> <?php echo $emailValid->getErrorMessage(); ?> </span> <br>

        <label for="optin">Opt In??</label><!--add legal-ese later--> <input type="checkbox" name="optin" required> <br>

        <?php echo $captchaValid->getCssClassName(); ?>
        <label for="captcha">captcha</label> <?php echo $math; ?> = <input type="text" name="captcha" value="<?php echo $captchaValid->getValue(); ?>" required><br>
        <span class="help-inline" id="errorCaptcha"> <?php echo $captchaValid->getErrorMessage(); ?> </span> <br>

        <input type="submit" value="Submit">

    </form>

</body>
</html>

【问题讨论】:

    标签: php forms validation


    【解决方案1】:

    我几乎忘记了这个问题,所以我知道我完全迟到了,但无论如何:还有几件事。

    1. 名称为answer 的输入不存在。因此$_POST['answer'] 的值将始终为 null - 然后模式 "/" . $_POST['answer'] . "/" 将始终为匹配所有内容的 //。 上次我没注意到。您可能想要验证 $_SESSION['answer'],而不是 $_POST['answer']

    2. session_start() 消失了 - 所以每次都会再次生成答案。

    3. 如果用户没有正确回答,您想重新生成验证码 - 所以在第 38 行 if ($firstnameValid-&gt;isValid() &amp;&amp; ... 的块中,您要添加 else 块。并生成新的验证码答案并将其存储到会话中,在那个新的else

    ===============第二次猜测===============

    我没有看到显示 HTML 表单的页面(文件)。所以我猜它在另一个包含的文件中。

    第一个猜测在底部,但还有更重要的问题,在行

     $captchaValid = ValidationResult::checkParameter("captcha", $_SESSION['answer'] == $_POST['answer'], 'Please try again');
    

    $_SESSION['answer'] == $_POST['answer'] 部分首先被评估,结果作为模式传递。所以你正在传递truefalse。 还。我不确定您如何获得 $_POST['captcha'] 和 $_POST['answer'] 的值。你会自动用正确的答案填充隐藏的输入“验证码”吗?

    您将captchafalse 传递给ValidationResult-&gt;checkParameter()。如果您想检查$_POST['captcha'] 是否与$_POST['answer'] 相同,我会作为模式(第二个参数)传递类似

    "/" . $_POST['answer'] . "/". 
    // for example: /12/
    

    这样它就创建了模式。您将针对该模式验证 $_POST['captcha']。

    ===============原始猜测===============

    我也猜想,当您提交表单时,您会重新加载整个页面。以便再次加载以下块:

    <?php   
    //captcha
    session_start();
    $digit1 = mt_rand(1, 10);
    $digit2 = mt_rand(1, 10);
    
    $math ="$digit1 + $digit2";
    $_SESSION['answer'] = $digit1 + $digit2;
    

    如果这是真的,那么您正在验证错误的数字。您首先生成新答案,然后对照它检查旧答案。

    检查答案是否已经设置,将是:

    if(!isset($_SESSION['answer'])) //If the answer doesn't already exists
    {
        // generate new answer
        $digit1 = mt_rand(1, 10);
        $digit2 = mt_rand(1, 10);
    
        $math ="$digit1 + $digit2";
        $_SESSION['answer'] = $digit1 + $digit2;
    }
    

    我是 Stackoverflow 的新手,所以我不完全确定这应该是答案还是评论,但无论如何,由于我的声誉,我还不能发布 cmets。

    希望对你有帮助:-)

    【讨论】:

    • 感谢您的回复!我根据您在我帖子末尾的建议添加了表单的 html,并进行了一些编辑。我不认为凌晨 3 点这很重要......无论如何,我尝试了你的建议,他们已经改进了一些,但他们仍然没有 100% 工作。在更改上述编辑中发布的代码后,验证码的所有答案都被验证为正确并发送到数据库。不知道是不是我的变量命名或者排列方式有问题?
    • var_dump($variable);可能有帮助 - 它打印出变量的内容(即使它是空字符串,或为假),或者如果未设置变量,则为 null。
    猜你喜欢
    • 2014-01-08
    • 1970-01-01
    • 2021-08-25
    • 2020-08-31
    • 1970-01-01
    • 2016-01-29
    • 2016-11-12
    • 1970-01-01
    • 2023-02-04
    相关资源
    最近更新 更多