How to use PDO connection in other classes
P粉293550575
P粉293550575 2023-08-24 15:10:58
0
1
484
<p>I feel like I have a problem understanding how object-oriented programming (OOP) works. I've changed the code so that it works, but I don't think it's the right way. Here's a scenario (no, I'm not creating the user login myself, this is just to understand OOP better): </p> <p>I have a database.php file:</p> <pre class="brush:php;toolbar:false;">class Database { /* Attributes */ private $conn; private $dsn = 'mysql:dbname=test;host=127.0.0.1'; private $user = 'root'; private $password = ''; /* Create database connection */ public function __construct() { try { $this->conn = new PDO($this->dsn, $this->user, $this->password); } catch (PDOException $e) { print "Error!: " . $e->getMessage() . ""; die(); } return $this->conn; } }</pre> <p>So in this class, I create a database connection and return the connection (object?)</p> <p>Then I have a second class, the famous User class (actually I don't use autoloading, but I know about it): </p> <pre class="brush:php;toolbar:false;">include "database.php"; class User { /* Attributes */ private $conn; /* Get database access */ public function __construct() { $this->conn = new Database(); } /* Login user */ public function login() { $stmt = $this->conn->prepare("SELECT username, usermail FROM user"); if($stmt->execute()) { while($rows = $stmt->fetch()) { $fetch[] = $rows; } return $fetch; } else { return false; } } }</pre> <p>These are my two classes. As you can see, no big deal. Now, don't be confused by the function name <code>login</code> - actually, I'm just trying to select some usernames and usermails from the database and display them. I tried to achieve it by: </p> <pre class="brush:php;toolbar:false;">$user = new User(); $list = $user->login(); foreach($list as $test) { echo $test["username"]; }</pre> <p>There is a problem here. When I execute this code I get the following error message: </p> <blockquote> <p>Uncaught Error: Call to undefined method Database::prepare()</p> </blockquote> <p>I'm not sure I really understand the cause of this error.</p> <p><strong>The code works fine when I change the following: </strong></p> <p>Changed <code>$conn</code> in database.php from private to public (I think this is bad...? But when it is private, I can only use it in the Database class Query is executed internally, right? So should I put all these queries in Database class? I think this is bad because in a big project it will become very huge...) </p> ; <p>The second change is: </p> <p>Change <code>$this->conn->prepare</code> in the user.php file to <code>$this->conn->conn->prepare< /code>. I really have no idea about this. </p> <p>I mean, in the constructor of <code>user.php</code>, I have a <code>$this->conn = new Database()</code>, Since new Database will return the connection object from the DB class, I really don't know why there must be a second <code>conn-></code></p>
P粉293550575
P粉293550575

reply all(1)
P粉451614834
  • Don't create a class like Database because it is of little use. It makes sense to create a database wrapper class if it adds some extra functionality to PDO. But given its current code, it's better to use raw PDO.
  • Create a single $db instance from the original PDO or your database class.
  • Pass it as a constructor parameter to every class that requires a database connection.

database.php:

<?php
$host = '127.0.0.1';
$db   = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$opt = [
    \PDO::ATTR_ERRMODE            => \PDO::ERRMODE_EXCEPTION,
    \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
    \PDO::ATTR_EMULATE_PREPARES   => false,
];
$pdo = new \PDO($dsn, $user, $pass, $opt);

user.php

<?php
class User {
    /* Properties */
    private $conn;

    /* Get database access */
    public function __construct(\PDO $pdo) {
        $this->conn = $pdo;
    }

    /* List all users */
    public function getUsers() {
        return $this->conn->query("SELECT username, usermail FROM user")->fetchAll();
    }
}

app.php

include 'database.php';
$user = new User($pdo);
$list = $user->getUsers();

foreach($list as $test) {
    echo $test["username"],"\n";
}

output:

username_foo
username_bar
username_baz

Check out my (the only correct) PDO tutorial for more details on PDO.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template