Access the PHP PDO object in another file

2019-09-20 09:02发布

问题:

I have a class called generic in generic.php. I have a signup.php file which has to perform SQL queries. However, I can't access the PDO object created in generic.php that's stored in the variable $db.

The Generic class looks like this:

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

I try to access the $db variable (in which the PDO object is stored), but I get an error saying Call to a member function prepare() on a non-object in.... This is how my signup.php file currently looks like:

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

I can't find a way to get the $db variable with the database connection in my signup.php file, so I can execute the query. I've tried $db = $generic->db, but that doesn't make any difference.

I'm new to OOP PHP and trying some stuff out. I hope this questions explains my problem.

回答1:

First, you didn't call the "connect_database" function, so your $db variable is null. By the way, I recommend naming the class with a descriptive name, for example "DBHandler".

You change the "connect_database" function to private, and simply call it in the constructor. Also, make $db private and set a getter function for more readable code.

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

Now you can use your code like this (notice I've changed the file name and class name):

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

UPDATE:

More so, You don't need to user bindParam unless your values will change between the bindParam and the execute call.

You can simply pass the values in an array to the execute:

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


回答2:

There are 2 problems: You are not setting your object property and you are not addressing it correctly afterwards:

  1. In your connect_database function you need to use $this->db instead of $db. As you are using it now, you set a variable in the local scope of the function and that is gone as soon as you exit that function.

  2. When you want to use your connection like that, you need $stmt = $generic->db->prepare($sql).



标签: php mysql oop pdo