php 致命错误:调用未定义的方法 Database::prepare()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19622038/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 19:47:47  来源:igfitidea点击:

Fatal error: Call to undefined method Database::prepare()

phppdofatal-error

提问by user2460790

I have created a separate class for database and users.

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

Database.php

数据库.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

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

 }




 }

Here is my Login page with username and password.

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

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





}

When I execute I get an error:

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

Call to undefined method Database::prepare()

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

回答by Cristian Bitoi

You create $dbhwhen you instantiate Database(), but instantiating the Database only returns an instance of your Database class, not your db connection. You should have a getDb to get your connection from database object:

$dbh在实例化 Database() 时创建,但实例化 Database 仅返回 Database 类的实例,而不是您的 db 连接。您应该有一个 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 construct only return an instance of your Database class, not your db connection

数据库构造只返回数据库类的实例,而不是数据库连接

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


}

回答by Houssem Cherif

add the method "getmyDB" to database file

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

and call it when you create the constructor in the file user.php

并在文件 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;
            }
        }
    }

and finally add test.php file

最后添加 test.php 文件

include "user.php";

$user = new User();
$list = $user->login();

 foreach($list as $test)
    {
    echo $test["username"];
    }

回答by vikingmaster

Your Databaseclass does not extend PDO neither it does implement prepare method.

您的Database类既不扩展 PDO 也不实现prepare method

In order to access your PDOobject, you must make it public and access like:

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

From Userclass:

User班级:

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

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

The best way would be to extend the PDOclass.

最好的方法是扩展PDO类。