Reputation: 325
I am trying to learn OOP php and as I was developing a login/register system, I noticed that I am calling the Database clase in every function in my Users class.
For example, like this:
<?php
class Users {
public function signUp($username, $email, $password){
$db = new Database;
$dbh = $db->connect();
$sql = "INSERT INTO users (username, email, password) VALUES (?, ?, ?)";
try {
$query = $dbh->prepare($sql);
$query->execute(array($username, $email, $password));
echo 'succ';
} catch (Exception $ex) {
echo $ex->getMessage();
}
}
Basically, without copying the whole file, I have a few functions that work with the database and in every single one of them I have to call these two lines:
$db = new Database;
$dbh = $db->connect();
So I looked up on the internet and found about the spl_autoload_register. It worked perfectly for the most part, however I can't seem to replace the two lines from above like this:
$db = new Database;
$dbh = Database::connect();
as I get another error from my Database class:
Using $this when not in object context in D:\xampp\htdocs\PHP OOP\customSystem\Classes\Class.Database.php on line 24
Line 24 is the return of this function
public function connect(){
return $this->conn;
}
and I am out of ideas of what to do now, but it won't solve my initial problem with calling the Database class in every function, too. So, what do I need to do?
Upvotes: 2
Views: 270
Reputation: 58444
You should pass in the DB class as a dependency.
It should look something like this
class Users {
private $dbh;
public function __construct(\PDO $dbh)
{
$this->dbh = $dbh;
}
public function signUp($username, $email, $password)
{
$sql = "INSERT INTO users (username, email, password) VALUES (?, ?, ?)";
try {
$query = $this->dbh->prepare($sql);
$query->execute(array($username, $email, $password));
echo 'succ';
} catch (Exception $ex) {
echo $ex->getMessage();
}
}
}
This approach lets you pass same PDO instance to all of the classes that needs it. You can also further improve the code, by using a factory, that is responsible for creating all classes, that need PDO as a dependency, as described in this answer.
Upvotes: 2
Reputation: 202
When you statically call a method Database::connect();
you can't refer to $this
.
$this
is a reference to existing instance of your object therein.
So, when you create new instance by new Database()
then you can use $this
pointer inside Database class methods.
Just learn more about static things and try with this:
class Database
{
private static $instance = null;
private static $conn = null;
private function __construct()
{
try {
$dbh = new PDO(DB_SOCKET_TYPE . ':host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8', DB_USER, DB_PASSWORD);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$conn = $dbh;
} catch (PDOException $e) {
echo $e->getMessage();
}
}
private function getDbConnection()
{
return self::$conn;
}
public static function connect()
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance->getDbConnection();
}
}
// how to use it? for eg.
$sql = 'INSERT INTO users (username, email, password) VALUES (?, ?, ?)';
$query = Database::connect()->prepare($sql);
$query->execute(array($username, $email, $password));
Sorry for any mistakes, but i wrote this quickly and did not test it
I hope it's useful
Upvotes: -1