I think I have a problem understanding how OOP works. I've changed the code so it works, but it's not the right way I think. The following scenario (no, I'm not creating the user login myself, it's really just for local developers to understand OOP better):
I have a database.php file:
class Database { /* Properties */ private $conn; private $dsn = 'mysql:dbname=test;host=127.0.0.1'; private $user = 'root'; private $password = ''; /* Creates 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; } }
So in this class I create a database connection and return that connection (object?)
Then I have the second class, the famous User class (actually I don't use autoloading, but I know about it):
include "database.php"; class User { /* Properties */ private $conn; /* Get database access */ public function __construct() { $this->conn = new Database(); } /* Login a 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; } } }
These are my two courses. As you can see, no big deal. Now, don't get confused by the function name login
- actually I'm just trying to select some usernames and usermails from the database and display them. I try to achieve this by:
$user = new User(); $list = $user->login(); foreach($list as $test) { echo $test["username"]; }
Here comes the problem. When I execute this code I get the following error message:
Uncaught Error: Call to undefined method Database::prepare()
And I'm not sure I really understand what causes this error.
The code runs fine when I change the following:
Change $conn
in database.php to public instead of private (I think this is bad...? But when it is private, I can only do it in the database class Query is executed internally, am I right? So I should put all these queries in database class? I think this is bad because in a big project it will become very big..)
The second change I want to make is:
Change $this->conn->prepare
in the user.php file to $this->conn->conn->prepare
. Here I really don't know why.
I mean, in the constructor of user.php
I have a $this->conn = new Database()
and since new Database will be The DB class returns my connection object, I really don't know why there has to be a second conn->
Database
class as it is useless. It makes sense to create a database wrapper if it adds some extra functionality to PDO. But given its current code, it's better to use plain PDO.Database.php:
user.php
app.php
Output:
Check out my (the only correct) PDO tutorial for more PDO details.