I am very new to OOP styled PHP, and I am trying to implement PDO as well. I found this nice little class online which handles the database connection, however I have no idea how to access it from another class. Here is the code:
class PDO_DBConnect {
static $db ;
private $dbh ;
private function PDO_DBConnect () {
$db_type = 'mysql'; //ex) mysql, postgresql, oracle
$db_name = 'postGal';
$user = 'user' ;
$password = 'pass' ;
$host = 'localhost' ;
try {
$dsn = "$db_type:host=$host;dbname=$db_name";
$this->dbh = new PDO ( $dsn, $user, $password);
$this->dbh->setAttribute(PDO::ATTR_PERSISTENT, true);
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch ( PDOException $e ) {
print "Error!: " . $e->getMessage () . "\n" ;
die () ;
}
}
public static function getInstance ( ) {
if (! isset ( PDO_DBConnect::$db )) {
PDO_DBConnect::$db = new PDO_DBConnect ( ) ;
}
return PDO_DBConnect::$db->dbh;
}
}
$db_handle = PDO_DBConnect::getInstance();
class Person
{
function __construct()
{
$STMT = $db_handle->prepare("SELECT title FROM posts WHERE id = ? AND author = ? LIMIT 20");
$STMT->execute(array('24', 'Michael'));
while ($result = $STMT->fetchObject())
{
echo $result->title;
echo "<br />";
}
}
}
How can I gain access to the $db_handle
variable inside of my Person class? Do i have to instantiate the variable inside of the Person class? If so, does that mean I will always have to call it as $this->db_handle
? I was hoping to avoid that. (I still only have a very basic understanding of variable scope with classes)
There are (at least) three ways to handle this. The most portable, and oft recommended is called "dependency injection", whereby you pass the database handle into your class via its __construct()
and store it in a class variable. Requires accessing it with $this->db
like you didn't want to have to do.
class Person {
// Member to hold the db handle
public $db;
public function __construct($db_handle) {
// Assign the handle to a class member variable in the constructor
$this->db = $db_handle;
}
public function otherFunc() {
$this->db; // do something
}
}
$person = new Person($db_handle);
Next method would be to instantiate the $db_handle
inside the constructor rather than passing it in. This is a little harder to test and debug.
class Person {
public $db;
public function __construct() {
$this->db = PDO_DBConnect::getInstance();
}
}
Finally, you can call $db_handle
as a global
whenever you use it in your class. This is perhaps the hardest to read and debug.
class Person {
public function __construct() {
global $db_handle;
}
public function otherFunc() {
global $db_handle;
$db_handle; // do something
}
}
You should use Dependency Injection:
$steve = new Person($db_handle);
And yes, using the syntax you're hoping to avoid is the way to do it. You can always assign the class variable to a local method one by saying $dbh = $this->db_handle;
which I believe is marginally faster.
If you really must do database work from inside your Person object (separation of concerns says that this should be taken care of elsewhere), you can either pass it as a constructor argument (based on your usage, it looks like that may be the way you want to go), or as a setter injection. For the former:
class Person
{
function __construct($db_handle)
{
// ... your existing code
Then you instantiate your person object like so:
$person = new Person($db_handle);
That's really the only way you can avoid needing to use $this->db_handler
without copying the variable into local scope.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With