【问题标题】:Access the PHP PDO object in another file访问另一个文件中的 PHP PDO 对象
【发布时间】:2015-08-04 10:54:41
【问题描述】:

我在 generic.php 中有一个名为 generic 的类。我有一个必须执行 SQL 查询的 signup.php 文件。但是,我无法访问存储在变量 $db 中的 generic.php 中创建的 PDO 对象。

Generic 类如下所示:

class Generic {
    public $db;

    public function connect_database() {
        define('USER', 'user');
        define('PASSWORD', 'password');

        // Database connection
        try {
            $connection_string = 'mysql:host=localhost;dbname=mydb;charset=utf8';
            $connection_array = array(
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
            );

            $db = new PDO($connection_string, USER, PASSWORD, $connection_array);
            echo 'Database connection established';
        }
        catch(PDOException $e) {
            $db = null;
        }
    }   
}

我尝试访问 $db 变量(其中存储了 PDO 对象),但我收到错误消息 Call to a member function prepare() on a non-object in...。这就是我的 signup.php 文件当前的样子:

// Require needed classes
require_once('generic.php');

// Create needed objects
$generic = new Generic();

$datetime = date("Y-m-d H:i:s");

try {
    $sql = "INSERT INTO user(
        email, 
        name, 
        username, 
        password
    ) 
    VALUES(
        :email, 
        :name, 
        :username, 
        :password 
    )";

    $stmt = $db->prepare($sql);

    $stmt->bindParam(':email', 'myemail@email.com', PDO::PARAM_STR);       
    $stmt->bindParam(':name', 'John Doe', PDO::PARAM_STR); 
    $stmt->bindParam(':username', 'johndow', PDO::PARAM_STR);
    // use PARAM_STR although a number  
    $stmt->bindParam(':password', 'test123', PDO::PARAM_STR);   

    $stmt->execute();
} 
catch(PDOException $e) {
    echo $e;
}

我在我的 signup.php 文件中找不到通过数据库连接获取 $db 变量的方法,因此我可以执行查询。我试过$db = $generic->db,但没有任何区别。

我是 OOP PHP 新手,正在尝试一些东西。我希望这个问题能解释我的问题。

【问题讨论】:

    标签: php mysql oop pdo


    【解决方案1】:

    首先,您没有调用“connect_database”函数,因此您的 $db 变量为空。 顺便说一句,我建议使用描述性名称命名类,例如“DBHandler”。

    您将“connect_database”函数更改为私有,然后在构造函数中简单地调用它。此外,将 $db 设为私有并设置 getter 函数以获得更易读的代码。

    class DBHandler {
        private $db;
    
        function __construct() {
            $this->connect_database();
        }
    
        public function getInstance() {
            return $this->db;
        }
    
        private function connect_database() {
            define('USER', 'user');
            define('PASSWORD', 'password');
    
            // Database connection
            try {
                $connection_string = 'mysql:host=localhost;dbname=mydb;charset=utf8';
                $connection_array = array(
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
                );
    
                $this->db = new PDO($connection_string, USER, PASSWORD, $connection_array);
                echo 'Database connection established';
            }
            catch(PDOException $e) {
                $this->db = null;
            }
        }   
    }
    

    现在你可以像这样使用你的代码了(注意我已经改变了文件名和类名):

    // Require needed classes
    require_once('dbhandler.php');
    
    // Create needed objects
    $dbh = new DBHandler();
    
    // Check if database connection established successfully
    if ($dbh->getInstance() === null) {
        die("No database connection");
    }
    
    $datetime = date("Y-m-d H:i:s");
    
    try {
        $sql = "INSERT INTO user(
            email, 
            name, 
            username, 
            password
        ) 
        VALUES(
            :email, 
            :name, 
            :username, 
            :password 
        )";
    
        $stmt = $dbh->getInstance()->prepare($sql);
    
        $stmt->bindParam(':email', 'myemail@email.com', PDO::PARAM_STR);       
        $stmt->bindParam(':name', 'John Doe', PDO::PARAM_STR); 
        $stmt->bindParam(':username', 'johndow', PDO::PARAM_STR);
        // use PARAM_STR although a number  
        $stmt->bindParam(':password', 'test123', PDO::PARAM_STR);   
    
        $stmt->execute();
    } 
    catch(PDOException $e) {
        echo $e;
    }
    

    更新:

    更重要的是,您不需要使用 bindParam,除非您的值会在 bindParam 和执行调用之间发生变化。

    您可以简单地将数组中的值传递给执行:

    $stmt->execute(array(':email' => 'email address', ':name' => 'Name', ':username' => 'User name', ':password' => 'Your password'));
    

    【讨论】:

    • 太好了,谢谢!您能否解释一下“更重要的是,您不需要用户 bindParam,除非您的值会在 bindParam 和执行调用之间发生变化。” bindParam 和 execute 之间的值如何以及为什么会发生变化?
    • 例如,当使用 BLOB 时,您必须使用 bindParam,因为您将从流中获取数据。或者,如果您准备了多个语句,并且有些语句依赖于其他语句的结果,并且您在事务中运行它们。在必须的情况下——不需要bindParam,因为你的值不会改变——所以你可以在execute方法中使用数组,我认为这是最简单的方法,或者你可以使用bindValue。
    • 好的,我明白了。非常感谢您的解释:)
    • 我认为getInstance() 之前的function 关键字丢失了。
    【解决方案2】:

    有 2 个问题:您没有设置对象属性并且之后没有正确解决它:

    1. 在您的connect_database 函数中,您需要使用$this->db 而不是$db。当您现在使用它时,您在函数的本地范围内设置了一个变量,并且一旦您退出该函数,该变量就会消失。

    2. 当你想这样使用你的连接时,你需要$stmt = $generic->db->prepare($sql)

    【讨论】:

    • 感谢您的回答! Ron 的解决方案更优雅一些,所以我将使用他的代码:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-02
    • 1970-01-01
    相关资源
    最近更新 更多