Php PDO致命错误:对非对象调用成员函数prepare()

Php PDO致命错误:对非对象调用成员函数prepare(),php,mysql,oop,pdo,Php,Mysql,Oop,Pdo,当我尝试在数据库中插入数据时出现此错误。我已经搜索了这个错误的原因,我认为我的代码是正确的,我不应该得到错误。我的代码如下: config.php <?php class DatabaseConnection{ public function __construct(){ try{ $pdo = new PDO('mysql:host=localhost;dbname=test','root',''); //'mysql:host=host;dbna

当我尝试在数据库中插入数据时出现此错误。我已经搜索了这个错误的原因,我认为我的代码是正确的,我不应该得到错误。我的代码如下:

config.php

<?php
class DatabaseConnection{
    public function __construct(){
        try{
        $pdo = new PDO('mysql:host=localhost;dbname=test','root',''); //'mysql:host=host;dbname=dbname','mysqluser','mysqlpassword'
        }
        catch (PDOException $e){
            exit('Database error');
        }   
    }
}
?>

functions.php

<?php

require "config.php";

class LoginRegister{
    function __construct(){
        $database= new DatabaseConnection();
    }

    public function registerUser($username,$password,$name,$email){

        global $pdo; //THIS IS THE LINE WITH ERROR
        $query=$pdo->prepare("SELECT id FROM usuarios WHERE nombre_usuario=? AND correo_e=?");
        $query->execute(array($username,$email));
        $num=$query->rowCount();

        if($num==0){
            $query = $pdo->prepare("INSERT INTO usuarios(nombre_usuario,nombre_real,password,correo_e) VALUES (?,?,?,?)");
            $query->execute(array($username,$password,$name,$email));
            return true;
        }else{
            return print "Username or E_mail in use";
        }
    }
}
?>

register.php

<?php

require_once "functions.php";
$user = new LoginRegister();
?>

...HTML CODE...

<?php
if($_SERVER['REQUEST_METHOD'] == 'POST'){
    $username=$_POST['nombre_usuario'];
    $password=$_POST['password'];
    $name=$_POST['nombre_real'];
    $email=$_POST['correo_e'];

    if(empty($username) or empty($password) or empty($name) or empty($email)){
        echo "Error... Field must not be empty";
    }else{
        $register = $user->registerUser($username,$password,$name,$email);
        if($register){
            echo "Register done <a href='login.php'>Click here</a> for login";
        }else{
            echo "Username or E_mail in use";
        }
    }
}
?>

...HTML CODE...

…HTML代码。。。
…HTML代码。。。
如您所见,我在registerUser函数中声明了变量$pdo,此外,包含名称、用户名、密码和电子邮件的变量也是同一函数的参数


我知道这是一个多次重复的问题,但我无法用其他问题中的解决方案解决此错误。

很抱歉,我必须说这是一个可怕的代码。你犯了所有最严重的错误。首先,永远不要使用全局,只是永远不要这样做。谷歌搜索它来解释原因。 现在,在构造函数中创建的变量只有作用域,因此它们在其他类或方法中永远不可用。这就是为什么$pdo不是一个pdo对象,它只是一个具有空值的局部变量。试试这个:

class DatabaseConnection{
    private $pdo;

    public function __construct(){
        try{
        $this->pdo = new PDO('mysql:host=localhost;dbname=test','root',''); //'mysql:host=host;dbname=dbname','mysqluser','mysqlpassword'
        }
        catch (PDOException $e){
            exit('Database error');
        }   
    }

    public function getPdo()
    {
        return $this->pdo;
}

class LoginRegister{
    private $database;

    function __construct(){
        $this->database= new DatabaseConnection();
    }

    public function registerUser($username,$password,$name,$email){

        $pdo = $this->database->getPdo();
        $query=$pdo->prepare("SELECT id FROM usuarios WHERE nombre_usuario=? AND correo_e=?");

现在这仍然很可怕,但至少它会起作用。您确实必须阅读一本好书中有关面向对象编程的内容,这本书还向您介绍了设计模式、SOLID、DRY和其他最佳实践。

您的代码有几个问题

在另一个答案中解释了这两种方法,这将使您的代码正常工作(最终全部被破坏),但这仍然是错误的方法,它将连接到数据库的对象数量是您拥有对象数量的两倍

这样更改DatabaseConnection类

class DatabaseConnection{
    public $pdo;
    public function __construct(){
        $user = 'root';
        $pass = '';
        $dsn  = 'mysql:charset=utf8;dbname=test;host=localhost;charset=utf8';
        $opt  = array(
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        );
        $this->pdo = new PDO($dsn, 'root', '', $opt);
    }
}
以这种方式更改LoginRegister构造函数

function __construct($db){
    $this->db= $db;
}
并以这种方式创建register.php

require_once "functions.php";
$db = new DatabaseConnection();
$user = new LoginRegister($db->pdo);
然后在LoginRegister中始终使用
$this->db
而不是
$pdo


使$db连接成为应用程序类的外部服务的主要思想。否则,它将与藐视全局一样,只是以另一种形式出现。

这里我使用了php单例PDO连接和mysql。希望这会有所帮助

<?php

class DB {
protected static $instance;
protected function __construct() {
if(empty(self::$instance)) {
        try {
            self::$instance = new PDO("mysql:host=localhost;dbname=techprojects", 'root', '');
            self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
        } catch(PDOException $error) {
            echo $error->getMessage();
        }
    }

}
public static function getInstance() {
    if(empty(self::$instance)) {
        try {
            new DB();
            //var_dump(self::$instance);
        } catch(PDOException $error) {
            echo $error->getMessage();
        }
    }
    //var_dump(self::$instance);
    return self::$instance;
}

private function __clone() {
    // Stopping Clonning of Object
}

private function __wakeup() {
    // Stopping unserialize of object
}
}
?>
<?php
try {
$db = DB::getInstance();
$db1 = DB::getInstance();
$sqlExample = 'SELECT * FROM keywords';
$stm = $db->prepare($sqlExample);
$stm->execute();
$result = $stm->fetchAll(PDO::FETCH_ASSOC);

var_dump($db);
var_dump($db1);
echo "<pre>";
print_r($result);
echo "</pre>";

} catch (Exception $e) {
print $e->getMessage();

}
 ?>


事实上,你刚刚在这里重新创造了“全球”。@你的常识哦,我真的有。我根本没有这样做。这些类变量在它们的类中仍然是私有的,这意味着它们不是全局的。顺便说一句,谢谢你的评分。@你的常识我说这是一段可怕的代码,但我不打算为他写这段代码,因为PDO类的依赖注入应该是这样的。我现在不打算在OOPs中上完整的一课,对吗?StackExchange是关于解决眼前的问题,并将提问者指向正确的方向方向,而不是得分和炫耀与聪明的符号。谢谢你的时间。当然,我没想到你会帮我解决这个错误,我只是想寻求一点帮助。你的评论没关系,我是OOP新手,我有很多东西要学。我想了解更多我的OOP技巧我上面的评论是针对“你的常识”而不是你自己。这就是屏幕名称前的@在这里的意思。他很高兴地贬低我们,也接受了我们的工作。我看到他甚至删除了他对拉斯克莱特和我的努力所给予的一点赞扬。