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

Posted

技术标签:

【中文标题】带有 PDO 的基于 PHP 类的用户系统 - 在非对象上调用成员函数 prepare()【英文标题】:PHP Class Based User System With PDO - Call to a member function prepare() on a non-object 【发布时间】:2012-11-02 07:37:46 【问题描述】:

为了解决我的问题,我进行了大量的研究、故障排除和搜索,但没有成功。所以这里是错误...

在非对象上调用成员函数prepare()

生成此错误的代码在我的用户身份验证类中,如下所示...

$this->dbManager->db->prepare('INSERT INTO users (email, password, user_salt, is_admin) VALUES (:email, :password, :user_salt, :is_admin)');

dbManager 来自 $db,我已将其传递到我的类的 __construct 中,如下所示...

public function __construct($db) 
        $this->siteKey = 'notImportant';
        $this->dbManager = $db;
    

$db 源自我的 sql 类,我需要在 index.php 所需的一个“引导”php 文件中使用它。

bootstrap.php代码如下...

<?php

// Load firePHP library
//require_once('FirePHPCore/FirePHP.class.php');
ob_start();
//$firephp = FirePHP::getInstance(true);

// Load all the classes/libs...
require_once 'classes/sql.class.php';

require_once 'classes/auth.class.php';
$db = sql::getInstance();
session_start();
$auth = new Auth($db);

require_once 'lib/handlepost.php';

最后,我的 sql.class.php 代码如下...

class sql 
    public static $db = false;
    private $database_host = '';
    private $database_user = '';
    private $database_pass = '';
    private $database_db = '';

    private function __construct() 
        if (self::$db === false) 
            $this -> connect();
        
        return self::$db;
    


    public static function getInstance() 
        if (!self::$db) 
            self::$db = new sql();
        

        return self::$db;
     


    private function connect() 
        $dsn = $this -> database_type . ":dbname=" . $this -> database_db . ";host=" . $this -> database_host;
        try 
            self::$db = new PDO($dsn, $this -> database_user, $this -> database_pass, array(PDO::mysql_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
            self::$db -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
         catch (PDOException $e) 
            //print_r($e->errorInfo);
            //echo 'Connection failed: ' . $e->getMessage();
        
     // End Connect


我是使用 PDO 的新手,这让我开始时有些困惑......

如果能帮助我解释我做错了什么,我们将不胜感激。

【问题讨论】:

【参考方案1】:

您看到的错误意味着$this-&gt;dbManager-&gt;db 不是对象。因此,尝试在其上调用方法 (prepare) 会给您一个错误。

编辑:对不起,我现在看到你的错误了。

Sql::$db 是一个静态成员,但您正在访问它,就像它是一个属性一样。你不能那样做。我建议将您的班级 sql 上的静态成员更改为常规属性。例如:从public static $db = false; 中删除static。将所有self::$db 替换为$this-&gt;db 并将getInstance 方法重写为:

public static function getInstance() 
  if (!self::$instance) 
    self::$instance = new self();
  
  return self::$instance;

所以基本上,您的错误与 PDO 无关,而是与静态与成员属性有关。

您可以尝试一起跳过Sql 课程:

class ConnectionManager 
  private static $db = false;
  private static $database_host = '';
  private static $database_user = '';
  private static $database_pass = '';
  private static $database_db = '';

  public static function getConnection() 
    if (!self::$db) 
      self::connect();
    
    return self::$db;
   

  private static function connect() 
    $dsn = self::database_type . ":dbname=" . self::database_db . ";host=" . self::database_host;
    try 
      self::$db = new PDO($dsn, self::database_user, self::database_pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
      self::$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
     catch (PDOException $e) 
      //print_r($e->errorInfo);
      //echo 'Connection failed: ' . $e->getMessage();
    
  

...

class Auth 
  public function __construct($db) 
    $this->siteKey = 'notImportant';
    $this->db = $db;
  

  public function foo() 
    $stmt = $this->db->prepare('INSERT INTO users (email, password, user_salt, is_admin) VALUES (:email, :password, :user_salt, :is_admin)');
    $stmt->execute(...);
  

...

$db = ConnectionManager::getConnection();
session_start();
$auth = new Auth($db); // <- Here $db is an actual instance of PDO

【讨论】:

我希望它如此简单,我也尝试过...这会产生如下错误...致命错误:调用未定义的方法 sql::prepare() 是的,没那么简单。您真正想做的是从该类的实例中获取静态成员。那是做不到的。我已经用更改代码的建议更新了我的答案。希望对您有所帮助。 确实有帮助,非常感谢。通过您推荐的一些更改,再加上一些调试,我现在可以正常工作了。谢谢! PS-我试图投票赞成您的答案,但是由于这实际上只是我个人第一次在 *** 上发布个人信息,因此我没有所需的代表。再次感谢!

以上是关于带有 PDO 的基于 PHP 类的用户系统 - 在非对象上调用成员函数 prepare()的主要内容,如果未能解决你的问题,请参考以下文章

PHP PDO 清理用户输入

制作 PDO mysql 静态连接类的最佳方法?

在带有 PDO 的 PHP 中,如何检查最终的 SQL 参数化查询? [复制]

在带有 PDO 的 PHP 中,如何检查最终的 SQL 参数化查询? [复制]

PHP - 使用带有 IN 子句数组的 PDO

PHP - 使用带有 IN 子句数组的 PDO