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.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.Finally, you can call
$db_handle
as aglobal
whenever you use it in your class. This is perhaps the hardest to read and debug.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:
Then you instantiate your person object like so:
That's really the only way you can avoid needing to use
$this->db_handler
without copying the variable into local scope.You should use Dependency Injection:
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.