search

Home  >  Q&A  >  body text

How to use PDO connection in other classes

<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粉293550575P粉293550575517 days ago509

reply all(1)I'll reply

  • P粉451614834

    P粉4516148342023-08-25 11:13:39

    • 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.

    reply
    0
  • Cancelreply