3

I just started switching my project form the mysql to PDO. In my project a new PDO Object is created more or less right a the beginning of the programm.

$dbh_pdo = new PDO("mysql:host=$db_url;dbname=$db_database_name", $db_user, $db_password);

Now I would like to use this handler (is that the correct name?) in some functions and classes. Is there a way to make objects global just like variables or am I trying something unspeakably stupid, because I couldn't find anything when searching the web ...

j0k
  • 22,600
  • 28
  • 79
  • 90
wowpatrick
  • 5,082
  • 15
  • 55
  • 86

3 Answers3

24

Yes, you can make objects global just like any other variable:

$pdo = new PDO('something');
function foo() {
   global $pdo;
   $pdo->prepare('...');
}

You may also want to check out the Singleton pattern, which basically is a global, OO-style.

That being said, I'd recommend you not to use globals. They can be a pain when debugging and testing, because it's hard to tell who modified/used/accessed it because everything can. Their usage is generally considered a bad practice. Consider reviewing your design a little bit.

I don't know how your application looks like, but say you were doing this:

class TableCreator {
   public function createFromId($id) {
       global $pdo;
       $stmt = $pdo->prepare('SELECT * FROM mytable WHERE id = ?');
       $stmt->execute(array($id));
       $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
       foreach ($rows as $row) {
           // do stuff
       }
   }
}

You should do that instead:

class TableCreator {
   protected $pdo;

   public function __construct(PDO $pdo) {
       $this->pdo = $pdo;
   }

   public function createFromId($id) {
       $stmt = $this->pdo->prepare('SELECT * FROM mytable WHERE id = ?');
       $stmt->execute(array($id));
       $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
       foreach ($rows as $row) {
           // do stuff
       }
   }
}

Since the TableCreator class here requires a PDO object to work properly, it makes perfect sense to pass one to it when creating an instance.

Gordon
  • 312,688
  • 75
  • 539
  • 559
netcoder
  • 66,435
  • 19
  • 125
  • 142
  • 1
    Thanks for your great answer! Always good to know right form the beginning what is good or bad practice. There is just one more question I have, I just started with OO a few weeks ago, so please bear with me. Have I got it right that instead of putting the $pdo in the function, before the function is called we take the existing, non-global $pdo (our handler) and turning it with $this->pdo $pdo into a class internal object that can be used inside the following function? Thanks again! – wowpatrick Jan 14 '11 at 22:08
  • @wowpatrick: Yes that's right. This way the PDO object is accessible only by the class that needs it. This is called *Encapsulation*. – netcoder Jan 15 '11 at 01:23
  • brilliant. An answer that not only answers the question, but educates on best practice as well. A big +1 from me. – Spudley Sep 03 '12 at 21:12
4

You'll use $GLOBALS['dbh_pdo'] instead of $dbh_pdo inside any functions. Or you can use the global keyword, and use $dbh_pdo (i.e. global $dbh_pdo).

Jeff Hubbard
  • 9,822
  • 3
  • 30
  • 28
  • Thanks! The first example you explained works fine, but I don't quite get the second one. I set global $dbh_pdo; before $dbh_pdo = new PDO, but that doesn't seem to work. – wowpatrick Jan 14 '11 at 21:50
  • 1
    You have to add that line in every function you want to use `$dbh_pdo` in, which is why I mentioned the `$GLOBALS` solution first--it's easier to remember to do. – Jeff Hubbard Jan 15 '11 at 02:49
0

You could also try using a Singleton to pass back a PDO object to you. That way you only ever have one PDO object (and one database connection) in any request which saves on memory/server resources.

Jeremy
  • 2,651
  • 1
  • 21
  • 28