0

This might not be a real problem at all, but I would like to know why this works.

The code is working the way I posted it here.

I've got a Database() class like this:

class Database extends PDO
{

    public function __construct()
    {
        $options = array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ, PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING);
        parent::__construct(DB_TYPE . ':host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8', DB_USER, DB_PASS, $options);
    }
}

This class gets called through the Controller:

class Controller
{
    function __construct()
    {
        Session::init();

        if (!isset($_SESSION['user_logged_in']) && isset($_COOKIE['rememberme'])) {
            header('location: ' . URL . 'login/loginWithCookie');
        }

        try {
            $this->db = new Database(); 
        } catch (PDOException $e) {
            die('Database connection could not be established.');
        }

        $this->view = new View();
    }
}

Notice the Database() class gets called here.

Now, I've got a "model", which needs the database connection to communicate with the database:

class Notes extends Controller
{    
    public function __construct()
    {
        parent::__construct();
    }

    public static function getSumNotes()
    {
        $sql = "SELECT COUNT(*) FROM table WHERE user_id = :user_id";
        $query = new Database();
        $query = $query->prepare($sql);
        $query->execute(array(':user_id' => $_SESSION['user_id']));

        return $query->fetchColumn();
    }
}

The thing that irritates me: the method Notes::getSumNotes() calls another new Database() class which is necessary to get my values from the table. Without this the connection would not work.

Question: Why do I have to call the Database() class twice although parent::__construct() from Notes gets the same variables and constructor from the "dads" (Controller) class?

Hope to get enlightened.

Thanks.

CRoemheld
  • 889
  • 7
  • 26
  • declare `protected $db` then use `return $this->db;` in your parent class and of course `private $db` in your `notes` class. – Ohgodwhy Jun 16 '14 at 23:34
  • You should pass a global database connection to your `Controller` class and its child classes; now you open a database connection for every object you create. And in the object itself you should be able to use `$this->db` – jeroen Jun 16 '14 at 23:36
  • @Ohgodwhy: Not working. When i `var_dump()` or `print_r()` out `$this->db`, nothing happens. It shows no arrays on my screen. – CRoemheld Jun 16 '14 at 23:38
  • @jeroen: I passed a global database connection and wrote this in my Notes class: `$query = $this->db->prepare($sql);` If this is right, it is still not working. – CRoemheld Jun 16 '14 at 23:48

1 Answers1

0

You don't have to call your Database object twice.
Notice your getSumNotes() method is static, hence you won't be able to call $this inside the method (this will raise an E_STRICT error so check your logs).

Either remove the static from your method or use this workaround:

class Notes extends Controller
{
    //  Notice the new variable has to be static as well
    public static $staticDb;

    public function __construct()
    {
        parent::__construct();
        //  Make sure the db variable exists in your parent class
        self::$staticDb = $this ->db;
    }

    public static function getSumNotes()
    {
        $sql = "SELECT COUNT(*) FROM table WHERE user_id = :user_id";

        //  Use the same DB connection
        $query = self::$staticDb;

        $query = $query->prepare($sql);
        $query->execute(array(':user_id' => $_SESSION['user_id']));

        return $query->fetchColumn();
    }
}

On a side note, your MVC structure is problematic. A model should not be an extension of a controller class.
More on that here, if you feel like it.

Community
  • 1
  • 1
LifeQuery
  • 3,202
  • 1
  • 26
  • 35
  • Thanks for your explanation. Unfortunately the result is the same as in the suggestions above (no array on my screen when var_dumped). In regard to the "models": those are not models at all, thats why i set it in doublequoted marks :) I was just giving an example, the real code is a little bit different. But this is the exact structure my code is in use right now. – CRoemheld Jun 17 '14 at 01:42
  • @CRoemheld This code works and you definitely should not have to instantiate the DB object twice. If the real code is different like you say, then I can't guess what's wrong with it. Either way, a DB connection should and can be passed to a child class. – LifeQuery Jun 17 '14 at 02:15
  • I passed the exact same variables to my script. I also passed a `protected $db` to the Controllers class. I also tried removing the "static". Result is the same as i said: The array is empty. But I'm really thankful for your explanation! :) @LifeQuery – CRoemheld Jun 17 '14 at 02:36