1

我将所有代码从 mysql 更改为 PDO,但我遇到了一些麻烦。我在这里阅读了很多信息以及 nettus 的教程,但仍然无法弄清楚为什么我的代码不起作用。

下面是 login.php PHP,当我按下登录时,你应该打开我的用户类并开始登录。

<?php

    require_once('../global.php');
    require_once('../assets/header.php');
    if (isLogged())
    {
        header("Location: $website_domain");
        exit;
    }

    if (isset($_POST['submit']))
    {
        $username = $_POST['username'];
        if(empty($_POST['password']))
        {
            $password == "";
        }
        else
        {
            $password = md5($_POST['password'].$_POST['username']);
        }

        $object = new User();
        $object->Login($username,$password);

    }

?>

这是我收到的错误: Fatal error: Call to a member function prepare() on a non-object in /home/astonish/public_html/labs.site.com/lock/includes/classes/user.class.php on line 32

如果您需要查看我的用户类,请询问,当你们只需要看到错误时,我不想用代码填充它。

用户类.php

<?php

    require_once('connection.php');

    // new data
    $ip    = $_SERVER['REMOTE_ADDR'];
    $hour  = date('h');
    $month = date('m');
    $date  = dateTime();

    class User
    {
        private $db;
        public function _construct() 
        {
            $this->db = new Connection();
            $this->db = $this->db->dbConnect(); 
        }

        public function Login($name, $pass) 
        {
            if(empty($name))
            {
                echo "Please input a username";
            }
            elseif(empty($pass))
            {
                echo "Please input a password";
            }
            elseif(!empty($name) && !empty($pass))
            {
                $st = $this->db->prepare("select * from users where username=? and password=?");
                $st->bindParam(1, $name);
                $st->bindParam(2, $pass);
                $st->execute();

                if($st->rowCount() == "1")
                {

                    // Delete failed attempts
                    $st = $db->prepare('DELETE FROM failedLogins WHERE ip = :ip');
                    $st->bindParam(':ip', $ip); // this time, we'll use the bindParam method
                    $st->execute();

                    // Get status of user
                    $result = $st->fetch(PDO::FETCH_ASSOC);
                    $result->status;

                    if ($fetch['status']==1)
                    {
                        $error = 'Your account is pending email.';
                    }
                    else if ($fetch['status']==2)
                    {
                        $_SESSION['main'] = md5(sha1($_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT'].$fetch['id']));
                        $_SESSION['uid'] = base64_encode($fetch['id']);

                        header("Location: $website_domain");
                        exit;
                    }
                    else if ($fetch['status']==5)
                    {
                        $error = 'Your account is inactive or was denied.';
                    }
                    else
                    {
                        $error = 'Invalid account status.';
                    }
                }
            }
            else
            {   
                $st = $this->db->prepare("INSERT INTO `failedLogins` (ip,hour,month,date) VALUES (:ip,:hour,:month,:date)");
                $st->execute(array(':ip'=>$ip, ':hour'=>$hour, ':month'=>$month, ':date'=>$date));

                echo  'The username or password entered is invalid.';
            }
        }

    }

?>

连接.php

class Connection 
    {
        public function dbConnect() 
        {
            return new PDO("mysql:host=localhost;dbname=astonish_viral", $mysql_user, $mysql_pass);
            /*try 
            {
                $db = new PDO("mysql:host=localhost;dbname=astonish_viral", $mysql_user, $mysql_pass);
                echo 'Connected to database';
            }
            catch(PDOException $e)
            {
                echo 'ERROR: ' . $e->getMessage();
            }*/
        }
    }

新错误:现在收到以下错误

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [1045] Access denied for user ''@'localhost' (using password: NO)' in /home/astonish/public_html/labs.site.com/lock/includes/classes/connection.php:12 Stack trace: #0 /home/astonish/public_html/labs.site.com/lock/includes/classes/connection.php(12): PDO->__construct('mysql:host=loca...', NULL, NULL) #1 /home/astonish/public_html/labs.site.com/lock/includes/classes/user.class.php(17): Connection->dbConnect() #2 /home/astonish/public_html/labs.site.com/lock/account/login.php(23): User->__construct() #3 {main} thrown in /home/astonish/public_html/labs.site.com/lock/includes/classes/connection.php on line 12
4

2 回答 2

1

我的猜测是您的PDO对象(假设您已经创建了一个)不在您的User::Login()方法范围内。

在这里进行一些假设,但假设您在其中创建PDO对象global.php,例如

$pdo = new PDO('mysql:host...');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

你应该在你的User班级注册这个,例如

class User {
    private $pdo;

    public function __construct(PDO $pdo) {
        $this->pdo = $pdo;
    }

    // etc

然后你可以在方法中使用这个对象User,例如

public function Login($username, $password) {
    $stmt = $this->pdo->prepare('SELECT ... ');
    $stmt->execute(array(
        'username' => $username,
        'password' => $password
    ));

    // etc
}

创建User类时,通过PDO构造函数传递实例

$object = new User($pdo); // pass $pdo object created in global.php
$object->Login($username, $password);

更新

看来您只是缺少$this->此行的前缀

// Delete failed attempts
$st = $db->prepare(...

应该

$st = $this->db->prepare(...

附录

我认为你不应该在每次实例化你的User类时都创建一个连接。相反,您应该独立创建连接并通过构造函数注入它。这样,您可以重新使用该PDO对象。

此外,您的Connection课程似乎是多余的。PDO如果您只支持一种类型的数据库,则无需将其包装在抽象层中,这是一个很棒的类。

于 2013-01-29T23:40:08.103 回答
1

那是您拼错构造函数的错字。由于您拼错了方法名称,因此永远不会调用“您的”构造函数,因此 $this->db 永远不会被初始化。

在 PHP 中定义构造函数有两种选择:

public function __construct()

请注意,作为构造函数需要两个下划线。您可以选择的另一个选择是将构造函数方法命名为类

public function User()

请注意,我建议第一种样式,因为如果您更改类名,则不必更改构造函数名称


您的代码中还有另一个语法错误。将 User.php 的第 41 行替换为

$st = $this->$db->prepare('DELETE FROM failedLogins WHERE ip = :ip');

(你错过了$this


您在问题更新中发布了另一个错误。你在哪里定义$mysql_user$mysql_pass在 Connection 类?

于 2013-01-30T00:09:01.360 回答