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

Posted

技术标签:

【中文标题】PDO 致命错误:在非对象上调用成员函数 prepare()【英文标题】:PDO Fatal error: Call to a member function prepare() on a non-object 【发布时间】:2015-12-30 06:25:49 【问题描述】:

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

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

?>

注册.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...

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

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

【问题讨论】:

***.com/questions/11597756/… 【参考方案1】:

这里我使用了 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();


 ?>

【讨论】:

【参考方案2】:

您的代码有几个问题。

在另一个答案中解释了两个,这将使您的代码工作(最终一切都被破坏了),但这仍然是错误的方法,它将连接到数据库的次数与你有很多对象

以这种方式更改 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-&gt;db 而不是$pdo

使$db 连接成为应用程序类的外部服务的主要思想。否则就和被鄙视的全局一样,只不过是另一种形式而已。

【讨论】:

【参考方案3】:

我很抱歉,但我必须说帽子可怕的代码。你正在犯所有最严重的错误。首先永远不要使用全局,永远不要这样做。谷歌它的解释为什么。 现在,您在构造函数中创建的变量仅在其中具有作用域,因此它们在您的其他类或方法中永远不可用。这就是为什么 $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 和其他最佳实践。

【讨论】:

实际上,您只是在这里重新定义了 global。 @你的常识哦,我真的有。我根本没有这样做。这些类变量在它们的类中仍然是私有的,这意味着它们不是全局的。顺便感谢您的标记。 @你的常识我说这是可怕的代码,但我不会为他写所有的代码,因为它应该是 PDO 类的依赖注入等。我不会我现在在这里上一堂 OOP 课程。StackExchange 是关于解决眼前的问题并为提问者指出正确的方向,而不是得分并用聪明的语义炫耀。 感谢您的宝贵时间。当然我没想到你会帮我解决错误,我只是在寻求一点帮助。你的评论没关系,我是 OOP 的新手,我有很多东西要学。我会提高我的 OOP 技能 我上面的 cmets 是针对“您的常识”而不是您自己。这就是屏​​幕名称之前的@在这里的含义。他很高兴给我们打分,也很乐意接受我们的工作。我看到他甚至删除了他对拉斯克拉特和我的努力的一点点赞誉。

以上是关于PDO 致命错误:在非对象上调用成员函数 prepare()的主要内容,如果未能解决你的问题,请参考以下文章

致命错误:在非对象上调用成员函数 fetch()?

致命错误:在非对象上调用成员函数 getLoginUrl()

致命错误:在非对象 cakephp 上调用成员函数 save()

致命错误:在非对象上调用成员函数 fetch_array()

带有 PDO 的基于 PHP 类的用户系统 - 在非对象上调用成员函数 prepare()

Zend_Mail generateMessage() 导致致命错误:在非对象上调用成员函数 getContent()