1

FIRSTLY: This question is not a duplicate. Here's why. My previous question on the topic was closed as a duplicate of this (of all things). That was not in the least bit helpful whatsoever - I didn't understand a damn thing. I'm completely new to OOP - I need an answer tailored to my level of understanding - I had no clue what the answers to the linked questions were talking about. Just because the question appears to be similar, the asker may not be - I specifically requested in my prior question an 'understandable' answer to my level of understanding anyway. So, I'll ask again (and again, if I need to). Here goes:


I'm still reasonably new to PHP overall, and even newer to Object Oriented PHP, having only just started educating myself on it within the past week, and I am still unable to grasp some concepts such as inheritance and what class abstraction is - some of it I've been able to pick up reasonably quickly as I've been working with PDO to handle my database connections and queries for a while now, but otherwise I'm still a newbie at OOPHP, so bear with me if my question seems a bit 'basic'.

I've got an initialization file (init.php) required at the top of each of my webpages, which, among other things, connects to a MySQL database using PDO as such:

try {
    $dbh = new PDO(conn. data here);
} catch(PDOException $e) {
    echo $e->getMessage();
}

So, as I understand it, on execution of this code, $dbh is now instantiated as a PDO object. At the bottom of my init.php file is a much of requires linking to function files, such as user.func.php, images.func.php, etc.

The problem is whenever I need to query the database from inside one of my functions, I need to declare $dbh as a global before I'm able to manipulate it, like so:

function myFunction {
    global $dbh; // Here's the problem!

    try {
        $stmt = $dbh->prepare(Some SQL here);
        $stmt->execute();
    } catch {
        // etc. 
    }
}

Now, the problem is not my understanding of why I have to declare as a global - I understand that much, but how I can avoid it. I've read some StackOverflow answers on why to avoid globals, I'm just not sure how.

How would I go about removing global $dbh from my code? Would I create a database handler class and pass my connection settings to the constructor method each time I instantiate it and use that instead? (Seems a bit redundant).

Not really sure how to replace my use of global variables, so help I can understand is definitely appreciated!

Community
  • 1
  • 1
marked-down
  • 9,958
  • 22
  • 87
  • 150
  • The fact that you don't understand the answer to a question doesn't mean that your question is not a duplicate. However, you now have at least one answer that should help you on your way. Good luck. – vascowhite Mar 27 '13 at 06:08
  • @vascowhite True, but even still, the relationship between my question and his seems to be very tenuous at best. I want to know how to stop using global variables in functions in my code, he wanted to know how to properly set up a PDO connection. If someone can please enlighten me as to how his question answers mine, it'd be appreciated! Thanks. – marked-down Mar 27 '13 at 06:20

2 Answers2

1

In very broad terms - you are asking here about Scope There are some specific theories that it would be useful to understand before ploughing on with writing code. I know it sometimes seems attractive, but taking a step back to learn some theory is really useful here.

The answer you linked to jumps straight into explaining dependency injection, but this might be a better place to start (How to explain dependency injection to a 5-year-old?) this comment in particular: https://stackoverflow.com/a/1639321/181707

Finally - I recommend that you look at some simple frameworks that handle some of this stuff - and learn from reading the source code.

A super simple depency injection container is Pimple:

http://pimple.sensiolabs.org/

Have a quick look at the introduction - it's not scary and should help you get the concepts involved.

Community
  • 1
  • 1
calumbrodie
  • 4,722
  • 5
  • 35
  • 63
  • Excellent answer. There is a good description of how PHP handles scope here http://php.net/manual/en/language.variables.scope.php – vascowhite Mar 27 '13 at 06:12
-1

You could avoid redundant use of code by extending classes. The new class gets all the public and protected functions from the extended class.

<?php
//$dbh stuff up here

class Main{
   public $dbh;
   function __construct() { //this magic function runs when the class is initiated.
       global $dbh;
       $this->dbh = $dbh;
       //dbh will be accessible for this whole class using $this->dbh 
   }
}

class imageClass extends Main{
    public function test(){
       if (isset($this->dbh){
           echo "it works";
       }
    }
}

class userClass extends Main{
   function __construct(){
       //this construct function overwrites the construct function in main so dbh
       //will not be accessible in this class
   }
}

imageFunc::test();

If you are so concerned with not reusing code why are you requiring init.php at the top of every page!! I think you might want to look into Model-View-Controller framework. I started with the blog tutorial on cakephp.org and you can check out jream on youtube, a tutorial of creating a MVC http://www.youtube.com/playlist?list=PL7A20112CF84B2229.

  • I down voted as you are recommending putting the $dbh variable into global scope. This is bad practice and is also what the OP specifically wants to avoid. – vascowhite Mar 27 '13 at 06:10