【问题标题】:OOP and AJAX form submission issuesOOP 和 AJAX 表单提交问题
【发布时间】:2013-04-24 20:16:27
【问题描述】:

通过 ajax 在下面提交我的表单后,即使登录信息正确,消息总是返回失败!我也用非 oop 风格对此进行了编码,它工作得很好,但是当我使用这种风格的代码时,它就挂断了。直播网站是http://andyholmes.me/demo/summersproperty/OOP/login.php,用户名是admin@summersproperty.com,密码是admin

login.php -

    <?PHP
session_start();

include('includes/class.login.php');

$login = new Login();


$token = $_SESSION['token'] = md5(uniqid(mt_rand(), true));

if ($_POST['ajax']) {
    exit($login->getStatus());
}

?>
<style>
    #message { display: none; cursor: pointer; }
    .loader { display: none; }
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
    $("#loginForm").submit(function(e) {
        $(this).fadeOut(300);
        $('.loader').delay(300).fadeIn(100);
        $.post("<?=$_SERVER['PHP_SELF'];?>", { username: $('#username').val(), password: $('#password').val(), ajax: true }).done(function(data) {
            if (data.logged_in == true) {
                // Redirect with javascript
                $('.loader').delay(2000).fadeOut(100);
                $('#message').html('<p>Success! We\'ll redirect you in a minute...</p>').delay(2200).fadeIn(200);
            } else {
                $('.loader').delay(2000).fadeOut(100);
                $('#message').html('<p>Failed... Click to try again!').delay(2200).fadeIn(200);
                $('#message').on('click', function(){
                    $(this).fadeOut(200);
                    $('#loginForm').delay(350).fadeIn(200);
                });
            }
        }); 
        return false;
    });
});
</script>
<form id="loginForm" method="POST" action="">
    <table>
        <tr><td>Username:</td><td><input type="text" name="username" id="username"/></td></tr>
        <tr><td>Password:</td><td><input type="password" name="password" id="password"/></td></tr>
    </table>
    <input type="hidden" name="token" value="<?=$token;?>"/>
    <input type="submit" name="login" value="Log In"/>
</form>
<div class="loader">
    <img src="loader.gif"/>
</div>
<div id="message"></div>

和登录类 -

<?PHP

class Login 
{
    private $_id;
    private $_username;
    private $_password;
    private $_passmd5;

    private $_errors;
    private $_access;
    private $_login;
    private $_token;

    public function __construct()
    {
        $this->_errors = array();
        $this->_login  = isset($_POST['login']) ? 1 : 0;
        $this->_access = 0;
        $this->_token  = $_POST['token'];

        $this->_id     = 0;
        $this->_username = ($this->_login) ? $this->filter($_POST['username']) : $_SESSION['username'];
        $this->_password = ($this->_login) ? $this->filter($_POST['password']) : '';
        $this->_passmd5  = ($this->_login) ? md5($this->_password) : $_SESSION['password'];

    }

    public function isLoggedIn()
    {
        ($this->_login) ? $this->verifyPost() : $this->verifySession();

        return $this->_access;
    }

    public function filter($var)
    {
        return preg_replace('/[^a-zA-Z0-9]/','',$var);
    }

    public function verifyPost()
    {
        try
        {
            if(!$this->isTokenValid())
                throw new Exception('Invalid form submission');

            if(!$this->isDataValid())
                throw new Exception('Invalid form data entered');

            if(!$this->verifyDatabase())
                throw new Exception('Invalid username/password combination');

        $this->_access = 1;
        $this->registerSession();
        }
        catch(Exception $e)
        {
            $this->_errors[] = $e->getMessage();
        }
    }

    public function verifySession()
    {
        if($this->sessionExist() && $this->verifyDatabase())
            $this->_access = 1;
    }

    public function verifyDatabase()
    {
        include('dbConfig.php');

        $data = mysql_query("SELECT user_id FROM users WHERE user_username = '{$this->_username}' AND user_password = '{$this->_passmd5}'");

        if(mysql_num_rows($data))
        {
            list($this->_id) = @array_values(mysql_fetch_assoc($data));
            return true;
        }
        else 
        {
            return false;
        }
    }

    public function isDataValid()
    {
        return (preg_match('/^[a-zA-Z0-9]/', $this->_username) && preg_match('/^[a-zA-Z0-9]/', $this->_password)) ? 1 : 0;
    }

    public function isTokenValid()
    {
        return (!isset($_SESSION['token']) || $this->_token != $_SESSION['token']) ? 0 : 1;
    }

    public function registerSession()
    {
        $_SESSION['id'] = $this->_id;
        $_SESSION['username'] = $this->_username;
        $_SESSION['password'] = $this->_passmd5;
    }

    public function sessionExist()
    {
        return (isset($_SESSION['username']) && isset($_SESSION['password'])) ? 1 : 0;
    }

    public function showErrors()
    {
        echo "<h3>Errors</h3>";
        foreach($this->_errors as $key=>$value)
            echo $value."<br>";
    }

    public function getStatus()
    {
    return json_encode(array('logged_in' => $this->isLoggedIn(), 'errors' => $this->showErrors()));
    }   
}

?>

顺便说一句,我知道我需要使用 PDO 等,但我只想在我更改数据库连接数据之前让脚本运行良好。我知道我很接近,但这真的很令人沮丧!

如果你能帮助我,我将不胜感激!

编辑说明:此代码已针对使用 user1781670 的建议后出现的问题进行了更新

【问题讨论】:

  • 并非所有使用类的东西都是 oop :-)
  • 好的...虽然不是我遇到的问题!哈哈
  • PHP 是在服务器而不是客户端执行的服务器端语言。因此,您在 $.post 回调函数中的 php 代码将在发送任何 ajax 请求之前执行
  • 哦,是的,我知道 :) 这就是我正在努力解决的问题。当然你可以看到我所有的错误都是通过类来处理的,你有什么建议?
  • 将您的 HTML(表单)放在一个页面上,将您的 PHP 代码放在另一个页面(处理页面)上。将 AJAX 请求发送到您的处理页面。

标签: php jquery ajax


【解决方案1】:
<?PHP
session_start();


include('includes/class.login.php');

$login = new Login();


$token = $_SESSION['token'] = md5(uniqid(mt_rand(), true));

if ($_POST['ajax']) {
    exit($login->getStatus());
}

?>
 <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
    $("#loginForm").submit(function(e) {
        $.post("<?=$_SERVER['PHP_SELF'];?>", { username: $('#username').val(), password: $('#password').val(), ajax: true }).done(function(data) {
            if (data.logged_in == true) {
                // Redirect with javascript
            } else {
                // Inject errors to html
                // data.errors
            }
        }); 
        return false;
    });
});
</script>
<form id="loginForm" method="POST" action="">
    <table>
        <tr><td>Username:</td><td><input type="text" name="username" id="username"/></td></tr>
        <tr><td>Password:</td><td><input type="password" name="password" id="password"/></td></tr>
    </table>
    <input type="hidden" name="token" value="<?=$token;?>"/>
    <input type="submit" name="login" value="Log In"/>
</form>

正如你所看到的,我修改了你的 jquery,删除了你的 PHP 代码,因为那不是它所在的地方,我也把语法改得更清楚了,至少对我来说是这样。另请注意,“数据”是您的 PHP 函数 getStatus 返回的 json,该函数将登录状态返回为 json。

现在您只需要创建返回 json 的 PHP 函数。也许可以帮助您结帐json_encode。如果您遇到困难,请告诉我们。

getStatus 函数示例:

JavaScript 对象类似于 PHP 中的关联数组,只是 JavaScript 对象可以具有函数。因此,您需要将关联数组传递给 json_encode 也就不足为奇了。

public function getStatus()
{
    return json_encode(array('logged_in' => $this->isLoggedIn(), 'errors' => $this->showErrors()));
}

$.post 自动知道它收到了 JSON(这是默认选项),因此您可以使用 data.logged_in 和 data.errors 访问它的属性。

这是问题所在:您显示您的登录表单,当用户提交表单时,您通过 ajax 打开连接并发送用户输入的数据,您希望服务器返回信息。但是这些数据将如何返回呢?你打算怎么处理?好吧,那是 JSON 的。这是一种编写 JavaScript 对象的语法,因此使用 json_encode 您返回一个 JSON,当您的 JavaScript 接收到该 JSON 时,您可以访问它的数据并检查它是否成功登录。

【讨论】:

  • 所以 getStatus 是我需要为错误等创建的函数吗?我假设我不能使用之前在我的类文件中创建的所有错误/数据处理?
  • 是的,你可以,就是这样。 JSON 是一种编写 javascript 对象的方式,按照这个想法,您可以将所有 PHP 对象状态传递给您的 javascript 代码。一个例子是:{ logged_in: false, errors: ['username can\'t be blank', 'password can\'t be blank'] }。从您的 javascript 中,您可以访问这些属性,例如 data.logged_in 和 data.errors。
  • 你可以告诉我很新鲜!绝对需要帮助哈哈
  • 我不太了解如何让这个 JSON 东西与一个名为 getStatus 的新函数一起工作
  • 嘿,我回来了,请查看我的更新答案,如果您需要更多帮助,请告诉我。
猜你喜欢
  • 2021-05-13
  • 1970-01-01
  • 1970-01-01
  • 2020-01-18
  • 1970-01-01
  • 1970-01-01
  • 2014-08-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多