Php 致命错误:调用未定义的方法数据库::prepare()

Php 致命错误:调用未定义的方法数据库::prepare(),php,pdo,fatal-error,Php,Pdo,Fatal Error,我为数据库和用户创建了一个单独的类 Database.php class Database{ private $db; public function __construct(){ /*** mysql hostname ***/ $hostname = 'localhost'; /*** mysql username ***/ $username = 'username_web'; /*** mysql password ***/ $password = '

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

Database.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();
        }





}
当我执行时,我得到一个错误:

调用未定义的方法数据库::prepare()


实例化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
数据库构造只返回数据库类的实例,而不返回数据库连接

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;
       }
 }


}

您的
数据库
类既不扩展PDO,也不实现
准备方法

要访问您的
PDO
对象,必须将其公开并进行如下访问:

用户
类:

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

最好的方法是扩展
PDO
类。

将方法“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"];
    }

有没有其他方法可以在不扩展PDO的情况下实现这一点?是的,没错,我很粗心。。您应该有一个函数
getDb
,在这里您可以获得连接并在
Users
类中使用它。。。se我编辑的postWow!我不明白为什么返回
$this->db
不起作用,但在函数中返回并调用函数却起作用!!这个经过编辑的解决方案也适用于我。结束每个用户实例都将创建自己的数据库连接,从而杀死您的数据库服务器。