Reputation:
I've a simple class, User which requires database access. I also require database access in several other classes, so my class.user.php looks like this:
include "config.php"
class User {
public $db;
public function __construct(PDO $db){
$this->db = $db;
global $db;
}
function LastLogin(){
// global $db; // if I uncomment this, it works for this function.
$pdo = $db->prepare("SELECT last_login FROM users WHERE username = ?");
$pdo->execute(array($username));
while($r = $pdo->fetchObject()){
echo $r->last_login;
}
}
}
Config.php looks like this:
$dsn = "mysql:host=localhost;dbname=db;charset=utf8";
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
$db = new PDO($dsn,'user','pass', $opt);
So let's say I have page called userdetails.php, and I want to know when the user has last logged in.
$user = new User($db);
$user->LastLogin();
This results in a error message like this:
Notice: Undefined variable: db in /home/www/class.user.php on line 12
Fatal error: Call to a member function prepare() on a non-object in/home/www/class.user.php on line 12
So I'm having problems with using pdo inside the class. It makes no sense to type "global $db" to every function, so what am I doing wrong?
Upvotes: 1
Views: 295
Reputation: 94642
try this
include "config.php"
class User {
public $db;
public function __construct($db){
$this->db = $db;
}
function LastLogin(){
$pdo = $this->db->prepare("SELECT last_login FROM users WHERE username = ?");
$pdo->execute(array($username));
while($r = $pdo->fetchObject()){
echo $r->last_login;
}
}
}
The global $db
is definitely not required and is bad practice as it destroys the encapsulation of a class.
The type hint PDO in __construct(PDO $db)
is also not actually legal as far as I know.
And while you have a property of $db
and loaded it with the correct handle, to use it chnage this
$pdo = $db->prepare("SELECT last_login FROM users WHERE username = ?");
To
$pdo = $this->db->prepare("SELECT last_login FROM users WHERE username = ?");
So you are using/addressing it correctly.
Upvotes: 1
Reputation: 3372
Remove global $db
from your constructor.
Use $this->db
instead of $db
in function LastLogin
Upvotes: 1
Reputation: 13128
As stated in the comments, remove the line:
global $db;
Also, you don't need to pass the PDO
either.
And instead of trying to reference it as
$db->prepare(....)
You want to reference it as:
$this->db->prepare(....)
since you're instantiating it as a variable accessible within the class.
Upvotes: 2