CAPTCHA未正确验证

时间:2017-03-24 08:40:09

标签: php forms validation

我在表单上工作,除了自定义验证码外,一切似乎都运行正常。无论我输入错误答案还是实际正确答案,表单都不会提交到数据库,并使用我的&#34重新加载表单;请再试一次"错误消息...我希望此字段的验证遵循与其他字段相同的格式,但不知道是否可行(它是验证部分中的$ 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');

通过几种不同的方式来判断我是否可以使其正常工作,但正如我所说,我甚至不知道这是否可行(因为它不是真正的正则表达式?)。我已经尝试删除&#34; == $ _ POST ...&#34;部分,用单引号和双引号等括起来,并得到错误或与以前相同的结果。如果我想要的是不可能的,我很欣赏有关替代解决方案的建议......

一些注意事项:非常对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>

1 个答案:

答案 0 :(得分:0)

我几乎忘记了这个问题,所以我知道我已经迟到了,但无论如何:还有更多的事情。

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

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

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

  4. ===============第二次猜测===============

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

    首先猜测是在底部,但是更重要的问题是在

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

    首先评估部分$_SESSION['answer'] == $_POST['answer'],并将结果作为模式传递。因此,您传递truefalse。 也。我不确定,你如何得到$ _POST ['captcha']和$ _POST ['回答']的值。你是否用正确的答案自动填充隐藏的输入'验证码'?

    您将captchafalse传递给ValidationResult->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的新手,所以我不完全确定,这应该是答案还是评论,但无论如何,由于我的声誉,我还不能发表评论。

    希望它有所帮助:-)