【问题标题】:Fatal error: Call to undefined method Database::prepare()致命错误:调用未定义的方法 Database::prepare()
【发布时间】:2013-11-06 11:20:02
【问题描述】:

我为数据库和用户创建了一个单独的类。

数据库.php

 class Database{

     private $db;


    public function __construct(){

  /*** mysql hostname ***/
$hostname = 'localhost';

/*** mysql username ***/
$username = 'username_web';

/*** mysql password ***/
$password = 'password_web';



try {
    $this->db = new PDO("mysql:host=$hostname;dbname=kamadhenu_web", $username, $password);
    /*** echo a message saying we have connected ***/

       }
catch(PDOException $e)
    {
    echo $e->getMessage();
    }

 }

  /*** Query Function ***/
 public function query($sql)
        {
        return $this->db->query($sql);
        }



 }

Users.php

class Users{

     private $db;

public function __construct($database) {
$this->db = $database;

}


     public function login($username, $password)
     {

        $query=$this->db->prepare("SELECT `password`, `id` FROM `users` WHERE `username` = ?");
        $query->bindValue(1, $username);
        try{
        $query->execute();
        $data = $query->fetch();
        $stored_password = $data['password'];
        $id = $data['id'];
        #hashing the supplied password and comparing it with the stored hashed password.
        if($stored_password === sha1($password)){
        return $id; 
        }else{
        return false;   
        }

        }catch(PDOException $e){
        die($e->getMessage());
}

 }




 }

这是我的登录页面,包含用户名和密码。

 login.php

include('database.php');
include('users.php');

$dbh= new Database();
$users= new Users($dbh);


if (isset($_POST['submit']))

{ 

$username= $_POST['username'];
$password= $_POST['password'];

    $login = $users->login($username, $password);




        if ($login === false) {
        $errors[] = 'Sorry, that username/password is invalid';
        }
        else {
        // username/password is correct and the login method of the $users object returns the user's id, which is stored in $login.

        $_SESSION['id'] = $login; // The user's id is now set into the user's session in the form of $_SESSION['id']
        #Redirect the user to home.php.
        header('Location: list-updates.php');
        exit();
        }





}

执行时出现错误:

调用未定义的方法 Database::prepare()

【问题讨论】:

    标签: php pdo fatal-error


    【解决方案1】:

    您在实例化 Database() 时创建 $dbh,但实例化数据库仅返回您的数据库类的实例,而不是您的数据库连接。您应该有一个 getDb 来从数据库对象获取连接:

    $dbClass = new Database();
    $dbh = $dbClass->getDb(); // here you get the connection
    $users= new Users($dbh);  // here you give to Users() the $dbh, that isn't your 
                              // connection.. it's just Database class
    

    Database 构造仅返回您的 Database 类的实例,而不是您的 db 连接

    class Database{
    
     private $db;
    
    
    public function __construct(){
    
        try {
         $this->db = new PDO("mysql:host=$hostname;dbname=kamadhenu_web", $username, $password);
        /*** echo a message saying we have connected ***/
    
       }
        catch(PDOException $e)
            {
                echo $e->getMessage();
           }    
     }
    
     public function getDb() {
           if ($this->db instanceof PDO) {
                return $this->db;
           }
     }
    
    
    }
    

    【讨论】:

    • 是的,是的,我很粗心......你应该有一个函数getDb,你可以在其中获得连接并在Users类中使用它......看我编辑的帖子
    • 哇!我不明白为什么返回$this->db 不起作用,但在函数内返回并调用该函数有效!!这个编辑后的解决方案也对我有用..
    【解决方案2】:

    将方法“getmyDB”添加到数据库文件中

    class Database
    
        {
        /* Properties */
        private $conn;
        private $dsn = 'mysql:dbname=test;host=127.0.0.1';
        private $user = 'root';
        private $password = '';
        /* Creates database connection */
        public
    
        function __construct()
            {
            try
                {
                $this->conn = new PDO($this->dsn, $this->user, $this->password);
                }
    
            catch(PDOException $e)
                {
                print "Error!: " . $e->getMessage() . "";
                die();
                }
    
            return $this->conn;
            }
    
        public function getmyDB()
            {
            if ($this->conn instanceof PDO)
                {
                return $this->conn;
                }
            }
        }
    

    当你在文件 user.php 中创建构造函数时调用它

    include "database.php";
    
    class User
    
        {
        /* Properties */
        private $conn;
        /* Get database access */
        public
    
        function __construct()
            {
            $this->conn = new Database();
            $this->conn = $this->conn->getmyDB();
            }
    
        /* Login a user */
        public
    
        function login()
            {
            $stmt = $this->conn->prepare("SELECT username, usermail FROM user");
            if ($stmt->execute())
                {
                while ($rows = $stmt->fetch())
                    {
                    $fetch[] = $rows;
                    }
    
                return $fetch;
                }
              else
                {
                return false;
                }
            }
        }
    

    最后添加 test.php 文件

    include "user.php";
    
    $user = new User();
    $list = $user->login();
    
     foreach($list as $test)
        {
        echo $test["username"];
        }
    

    【讨论】:

    • 结束每个用户实例都会创建自己的数据库连接,杀死你的数据库服务器。
    【解决方案3】:

    您的 Database 类没有扩展 PDO,也没有实现 prepare method

    为了访问您的PDO 对象,您必须将其设为公开并访问:

    来自User类:

    $this->db->db->prepare();

    最好的方法是扩展PDO 类。

    【讨论】:

    • 有没有其他方法可以在不扩展 PDO 的情况下做到这一点?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    • 2017-09-19
    • 1970-01-01
    • 2020-02-23
    • 2015-01-28
    相关资源
    最近更新 更多